Wiele tweetów, które importuję, ma ten problem, gdy czytają
b'I posted a new photo to Facebook'
Zbieram b
, że jest to bajt. Ale okazuje się to problematyczne, ponieważ w moich plikach CSV, które piszę, b
nie znika i przeszkadza w przyszłym kodzie.
Czy istnieje prosty sposób na usunięcie tego b
przedrostka z moich wierszy tekstu?
Pamiętaj, że wydaje mi się, że muszę mieć tekst zakodowany w utf-8 lub tweepy ma problemy z wyciągnięciem ich z sieci.
Oto treść linku, który analizuję:
https://www.dropbox.com/s/sjmsbuhrghj7abt/new_tweets.txt?dl=0
new_tweets = 'content in the link'
Próba kodu
outtweets = [[tweet.text.encode("utf-8").decode("utf-8")] for tweet in new_tweets]
print(outtweets)
Błąd
UnicodeEncodeError Traceback (most recent call last)
<ipython-input-21-6019064596bf> in <module>()
1 for screen_name in user_list:
----> 2 get_all_tweets(screen_name,"instance file")
<ipython-input-19-e473b4771186> in get_all_tweets(screen_name, mode)
99 with open(os.path.join(save_location,'%s.instance' % screen_name), 'w') as f:
100 writer = csv.writer(f)
--> 101 writer.writerows(outtweets)
102 else:
103 with open(os.path.join(save_location,'%s.csv' % screen_name), 'w') as f:
C:\Users\Stan Shunpike\Anaconda3\lib\encodings\cp1252.py in encode(self, input, final)
17 class IncrementalEncoder(codecs.IncrementalEncoder):
18 def encode(self, input, final=False):
---> 19 return codecs.charmap_encode(input,self.errors,encoding_table)[0]
20
21 class IncrementalDecoder(codecs.IncrementalDecoder):
UnicodeEncodeError: 'charmap' codec can't encode characters in position 64-65: character maps to <undefined>
Odpowiedzi:
trzeba zdekodować
bytes
z was chce ciąg:b = b'1234' print(b.decode('utf-8')) # '1234'
źródło
.encode("utf-8").decode("utf-8")
nie robi absolutnie nic (jeśli w ogóle działa) ... jesteś na Pythonie 3, prawda? py3 ma silne rozróżnienie międzybytes
astr
. coś w twoim kodzie wydaje się używaćcp1252
kodowania ... możesz spróbować otworzyć plik za pomocąopen(..., mode='w', encoding='utf-8')
i tylko pisaćstr
do pliku; lub zapomnisz o całym kodowaniu i napisz plik binarnie:open(..., mode='wb')
(zwróć uwagę nab
) i pisz tylkobytes
. To pomaga?"b'Due to the storms this weekend, we have rescheduled the Blumenfield Bike Ride for Feb 26. Hope to see you there.\xe2\x80\xa6'"
.encode("utf-8").decode("utf-8")
że cokolwiek zrobię, ale ludzie tutaj wydawali się uważać, że to była właściwa odpowiedź, co nie jest tak daleko, jak widzę.C:\Users\Stan Shunpike\Anaconda3\lib\encodings\cp1252.py
. prawdopodobnie powinieneś spróbować dowiedzieć się, jak / gdzie to jest używane. oh, i używaszcsv.writer
; w takim przypadku musisz napisaćstr
rzeczywiście niebytes
. czy otrzymujesz rzeczy odrequests
? kodowanie otrzymane z zasobu internetowego może się różnić odutf-8
.Po prostu informuje cię, że drukowany obiekt nie jest łańcuchem, a raczej obiektem bajtowym jako literałem bajtowym . Ludzie wyjaśniają to w niepełny sposób, więc oto moje podejście.
Rozważ utworzenie obiektu bajtowego poprzez wpisanie literału bajtowego (dosłowne zdefiniowanie obiektu bajtowego bez faktycznego używania obiektu bajtowego, np. Przez wpisanie b '') i przekonwertowanie go na obiekt łańcuchowy zakodowany w utf-8. (Zauważ, że konwersja oznacza tutaj dekodowanie )
byte_object= b"test" # byte object by literally typing characters print(byte_object) # Prints b'test' print(byte_object.decode('utf8')) # Prints "test" without quotations
Widzisz, że po prostu stosujemy tę
.decode(utf8)
funkcję.Bajty w Pythonie
https://docs.python.org/3.3/library/stdtypes.html#bytes
Literały ciągów są opisane za pomocą następujących definicji leksykalnych:
https://docs.python.org/3.3/reference/lexical_analysis.html#string-and-bytes-literals
stringliteral ::= [stringprefix](shortstring | longstring) stringprefix ::= "r" | "u" | "R" | "U" shortstring ::= "'" shortstringitem* "'" | '"' shortstringitem* '"' longstring ::= "'''" longstringitem* "'''" | '"""' longstringitem* '"""' shortstringitem ::= shortstringchar | stringescapeseq longstringitem ::= longstringchar | stringescapeseq shortstringchar ::= <any source character except "\" or newline or the quote> longstringchar ::= <any source character except "\"> stringescapeseq ::= "\" <any source character> bytesliteral ::= bytesprefix(shortbytes | longbytes) bytesprefix ::= "b" | "B" | "br" | "Br" | "bR" | "BR" | "rb" | "rB" | "Rb" | "RB" shortbytes ::= "'" shortbytesitem* "'" | '"' shortbytesitem* '"' longbytes ::= "'''" longbytesitem* "'''" | '"""' longbytesitem* '"""' shortbytesitem ::= shortbyteschar | bytesescapeseq longbytesitem ::= longbyteschar | bytesescapeseq shortbyteschar ::= <any ASCII character except "\" or newline or the quote> longbyteschar ::= <any ASCII character except "\"> bytesescapeseq ::= "\" <any ASCII character>
źródło
Musisz go zdekodować, aby przekonwertować go na ciąg. Sprawdź tutaj odpowiedź na temat literału bajtów w python3 .
In [1]: b'I posted a new photo to Facebook'.decode('utf-8') Out[1]: 'I posted a new photo to Facebook'
źródło
encode("utf-8")
błędu, pojawiają się błędy. I, jak wspomniałem tutaj, usunięcie stackoverflow.com/q/41915383/4422095 nie rozwiązało problemu. Nawet jeśli używam dekodowania zgodnie z sugestią, nadal pojawia się błąd. Opublikuję to w poście.utf-8
był przykładem.**** Jak usunąć znaki b '', które są dekodowanym ciągiem w Pythonie ****
import base64 a='cm9vdA==' b=base64.b64decode(a).decode('utf-8') print(b)
źródło
W Pythonie 3.6 z django 2.0 dekodowanie literału bajtowego nie działa zgodnie z oczekiwaniami. Tak, otrzymuję właściwy wynik, gdy go drukuję, ale wartość b 'jest nadal obecna, nawet jeśli wydrukujesz ją poprawnie.
To właśnie je koduję
uid': urlsafe_base64_encode(force_bytes(user.pk)),
Oto, co im dekoduję:
Oto, co mówi django 2.0:
Koduje bajtest w base64 do użycia w adresach URL, usuwając wszelkie końcowe znaki równości.
Dekoduje ciąg zakodowany w standardzie base64, dodając z powrotem wszystkie końcowe znaki równości, które mogły zostać usunięte.
To jest plik my account_activation_email_test.html
{% autoescape off %} Hi {{ user.username }}, Please click on the link below to confirm your registration: http://{{ domain }}{% url 'accounts:activate' uidb64=uid token=token %} {% endautoescape %}
Oto odpowiedź mojej konsoli:
Content-Type: tekst / zwykły; charset = "utf-8" Wersja MIME: 1.0 Content-Transfer-Encoding: 7bit Temat: Aktywuj swoje konto MySite Od: webmaster @ localhost Do: [email protected] Data: piątek, 20 kwietnia 2018 06:26:46 - 0000 Identyfikator wiadomości: <152420560682.16725.4597194169307598579@Dash-U>
Cześć użytkowniku,
Kliknij poniższy link, aby potwierdzić rejestrację:
http://127.0.0.1:8000/activate/b'MjU'/4vi-fasdtRf2db2989413ba/
jak widzisz
uid = b'MjU'
spodziewany
uid = MjU
test w konsoli:
$ python Python 3.6.4 (default, Apr 7 2018, 00:45:33) [GCC 5.4.0 20160609] on linux Type "help", "copyright", "credits" or "license" for more information. >>> from django.utils.http import urlsafe_base64_encode, urlsafe_base64_decode >>> from django.utils.encoding import force_bytes, force_text >>> var1=urlsafe_base64_encode(force_bytes(3)) >>> print(var1) b'Mw' >>> print(var1.decode()) Mw >>>
Po zbadaniu wydaje się, że jest on powiązany z Pythonem 3. Moje obejście było dość proste:
'uid': user.pk,
otrzymuję go jako uidb64 w mojej funkcji aktywacji:
i voila:
Content-Transfer-Encoding: 7bit Subject: Activate Your MySite Account From: webmaster@localhost To: [email protected] Date: Fri, 20 Apr 2018 20:44:46 -0000 Message-ID: <152425708646.11228.13738465662759110946@Dash-U> Hi testuser, Please click on the link below to confirm your registration: http://127.0.0.1:8000/activate/45/4vi-3895fbb6b74016ad1882/
teraz działa dobrze. :)
źródło
Zrobiłem to, kodując tylko wyjście za pomocą utf-8. Oto przykład kodu
new_tweets = api.GetUserTimeline(screen_name = user,count=200) result = new_tweets[0] try: text = result.text except: text = '' with open(file_name, 'a', encoding='utf-8') as f: writer = csv.writer(f) writer.writerows(text)
tj .: nie koduj podczas zbierania danych z API, koduj tylko wyjście (drukuj lub zapisuj).
źródło
Zakładając, że nie chcesz od razu dekodować go ponownie, tak jak sugerują inni, możesz przeanalizować go na ciąg, a następnie po prostu usunąć początkowy
'b
i końcowy'
.>>> x = "Hi there 😄" >>> x = "Hi there 😄".encode("utf-8") >>> x b"Hi there \xef\xbf\xbd" >>> str(x)[2:-1] "Hi there \\xef\\xbf\\xbd"
źródło
Chociaż pytanie jest bardzo stare, myślę, że może być pomocne dla tego, kto ma ten sam problem. Tutaj teksty to ciąg jak poniżej:
text= "b'I posted a new photo to Facebook'"
Dlatego nie możesz usunąć b przez zakodowanie go, ponieważ nie jest to bajt. Wykonałem następujące czynności, aby go usunąć.
cleaned_text = text.split("b'")[1]
który da
"I posted a new photo to Facebook"
źródło
"I posted a new photo to Facebook'"
. W każdym razie nie o to chodzi w tym pytaniu.