Un certain nombre de tweets que j'importe ont ce problème là où ils lisent
b'I posted a new photo to Facebook'
Je rassemble le b
indique que c'est un octet. Mais cela s'avère problématique car dans mes fichiers CSV que je finis par écrire, le b
ne disparaît pas et interfère dans le code futur.
Existe-t-il un moyen simple de supprimer ce b
préfixe de mes lignes de texte?
Gardez à l'esprit que je semble avoir besoin d'avoir le texte encodé en utf-8 ou tweepy a du mal à les extraire du Web.
Voici le contenu du lien que j'analyse:
https://www.dropbox.com/s/sjmsbuhrghj7abt/new_tweets.txt?dl=0
new_tweets = 'content in the link'
Tentative de code
outtweets = [[tweet.text.encode("utf-8").decode("utf-8")] for tweet in new_tweets]
print(outtweets)
Erreur
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>
Réponses:
vous devez décoder le
bytes
de vous voulez une chaîne:b = b'1234' print(b.decode('utf-8')) # '1234'
la source
.encode("utf-8").decode("utf-8")
ne fait absolument rien (si ça marche du tout) ... vous êtes sur python 3, non? py3 a une forte distinction entrebytes
etstr
. quelque chose dans votre code semble utiliser l'cp1252
encodage ... vous pouvez essayer d'ouvrir votre fichier avecopen(..., mode='w', encoding='utf-8')
et n'écrire questr
dans le fichier; ou vous oubliez tout l'encodage et écrivez le fichier en binaire:open(..., mode='wb')
(notez leb
) et écrivez seulementbytes
. Est ce que ça aide?"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")
je ferais quoi que ce soit, mais les gens ici semblaient penser que c'était la bonne réponse, ce qui n'est pas aussi loin que je peux voir.C:\Users\Stan Shunpike\Anaconda3\lib\encodings\cp1252.py
. vous devriez probablement essayer de savoir comment / où cela est utilisé. oh, et vous utilisez lecsv.writer
; dans ce cas, vous devez enstr
effet écrire un nonbytes
. obtenez-vous des chosesrequests
? l'encodage obtenu à partir d'une ressource Web peut différer deutf-8
.Cela vous permet simplement de savoir que l'objet que vous imprimez n'est pas une chaîne, mais plutôt un objet octet sous forme de littéral d'octet . Les gens expliquent cela de manière incomplète, voici donc mon avis.
Envisagez de créer un objet octet en tapant un littéral octet (définissant littéralement un objet octet sans utiliser réellement un objet octet, par exemple en tapant b '') et en le convertissant en un objet chaîne codé en utf-8. (Notez que convertir ici signifie décoder )
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
Vous voyez que nous appliquons simplement la
.decode(utf8)
fonction.Octets en Python
https://docs.python.org/3.3/library/stdtypes.html#bytes
Les littéraux de chaîne sont décrits par les définitions lexicales suivantes:
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>
la source
Vous devez le décoder pour le convertir en chaîne. Vérifiez la réponse ici à propos des octets littéraux en python3 .
In [1]: b'I posted a new photo to Facebook'.decode('utf-8') Out[1]: 'I posted a new photo to Facebook'
la source
encode("utf-8")
erreurs, j'obtiens. Et, comme je l'ai mentionné ici, la suppression de stackoverflow.com/q/41915383/4422095 ne l'a pas résolue. Même si j'utilise le décodage comme vous le suggérez, j'obtiens toujours une erreur. Je publierai cela dans le post.utf-8
était un exemple.**** Comment supprimer les caractères b '' qui est une chaîne décodée en python ****
import base64 a='cm9vdA==' b=base64.b64decode(a).decode('utf-8') print(b)
la source
Sur python 3.6 avec django 2.0, le décodage sur un littéral d'octet ne fonctionne pas comme prévu. Oui, j'obtiens le bon résultat lorsque je l'imprime, mais la valeur b est toujours là même si vous l'imprimez correctement.
C'est ce que j'encode
uid': urlsafe_base64_encode(force_bytes(user.pk)),
C'est ce que je décode:
Voici ce que dit django 2.0:
Encode une chaîne d'octets en base64 pour une utilisation dans les URL, en supprimant tout signe égal à la fin.
Décode une chaîne encodée en base64, en rajoutant tout signe égal à la fin qui aurait pu être supprimé.
Ceci est mon fichier 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 %}
Voici ma réponse de console:
Content-Type: texte / brut; charset = "utf-8" Version MIME: 1.0 Content-Transfer-Encoding: 7bit Objet: Activez votre compte MySite De: webmaster @ localhost À: [email protected] Date: Ven, 20 Apr 2018 06:26:46 - 0000 ID de message: <152420560682.16725.4597194169307598579@Dash-U>
Salut testuser,
Veuillez cliquer sur le lien ci-dessous pour confirmer votre inscription:
http://127.0.0.1:8000/activate/b'MjU'/4vi-fasdtRf2db2989413ba/
comme vous pouvez le voir
uid = b'MjU'
attendu
uid = MjU
test dans la console:
$ 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 >>>
Après enquête, il semble que cela soit lié à python 3. Ma solution de contournement était assez simple:
'uid': user.pk,
je le reçois comme uidb64 sur ma fonction d'activation:
et 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/
maintenant cela fonctionne très bien. :)
la source
Je l'ai fait en encodant uniquement la sortie en utilisant utf-8. Voici l'exemple de code
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)
c'est-à-dire: ne pas encoder lors de la collecte de données depuis l'API, encoder uniquement la sortie (impression ou écriture).
la source
En supposant que vous ne vouliez pas le décoder immédiatement comme d'autres le suggèrent ici, vous pouvez l'analyser en une chaîne, puis supprimer simplement le début
'b
et la fin'
.>>> 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"
la source
Bien que la question soit très ancienne, je pense qu'elle peut être utile pour savoir qui est confronté au même problème. Ici, les textes sont une chaîne comme ci-dessous:
text= "b'I posted a new photo to Facebook'"
Ainsi, vous ne pouvez pas supprimer b en l'encodant car ce n'est pas un octet. J'ai fait ce qui suit pour le supprimer.
cleaned_text = text.split("b'")[1]
qui donnera
"I posted a new photo to Facebook"
la source
"I posted a new photo to Facebook'"
. De toute façon, ce n’est pas de cela qu’il s’agit.