143 votes

Comment puis-je me débarrasser du préfixe b dans une chaîne en python?

Un tas de tweets je suis importation rencontrez ce problème où qu'ils lisent

b'I posted a new photo to Facebook'

Je rassemble l' b indique qu'il est d'un octet. Mais cela s'avère problématique, car dans mes fichiers CSV que j'arrive à la fin de l'écriture, l' b ne va pas loin et qui interfère dans le futur code.

Est-il un moyen simple de supprimer ce b préfixe de mes lignes de texte?

Gardez à l'esprit, j'ai l'impression d'avoir besoin d'avoir le texte encodé en utf-8 ou tweepy a de la difficulté à les tirer à partir du web.


Voici le lien contenu, je suis d'analyser:

https://www.dropbox.com/s/sjmsbuhrghj7abt/new_tweets.txt?dl=0

new_tweets = 'content in the link'

Code Tentative

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>

230voto

hiro protagonist Points 1983

vous devez décoder le bytes d'entre vous voulez une chaîne:

 b = b'1234'
print(b.decode('utf-8'))  # '1234'
 

27voto

Jonathan Komar Points 511

Il est juste de vous laisser savoir que l'objet de l'impression n'est pas une chaîne de caractères, plutôt un octet à l'objet que d'un octet littérale. Les gens expliquent ce incomplète façons, voici donc mon point de vue.

Envisager la création d'un octet objet en tapant un octet littéral (littéralement la définition d'un octet objet sans l'aide d'un octet de l'objet par exemple en tapant b") et de le convertir en un objet chaîne de caractères codée en utf-8. (Notez que la conversion ici des moyens de décodage)

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 il suffit d'appliquer l' .decode(utf8) fonction.

Octets en Python

https://docs.python.org/3.3/library/stdtypes.html#bytes

Les littéraux de chaîne sont décrites par la suite lexicale définitions:

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>

8voto

salman wahed Points 5555

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'
 

3voto

Sur python 3.6 avec django 2.0, décodage sur un octet littérale ne fonctionne pas comme prévu. Ouais j'obtiens le bon résultat quand j'ai l'impression, mais le b'value " est toujours là, même si vous l'imprimer à droite.

C'est ce qui im encodage

uid': urlsafe_base64_encode(force_bytes(user.pk)),

C'est ce qui im décodage:

uid = force_text(urlsafe_base64_decode(uidb64))

C'est ce que django 2.0 dit :

urlsafe_base64_encode(s)[source]

Code pour une bytestring en base64 pour une utilisation dans les Url, le décapage de tous les signes égal.

urlsafe_base64_decode(s)[source]

Décode une chaîne encodée en base64, en ajoutant tous les signes d'égalité qui pourraient avoir été dépouillé.


C'est mon account_activation_email_test.html fichier

{% 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 %}

C'est ma réponse de la console:

Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Sujet: Activer Votre Monsite Compte De: webmaster@localhost Pour: testuser@yahoo.com Date: Fri, 20 Avril 2018 06:26:46 -0000 Message-ID: <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'

attendue uid = MjU


test de 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 son lié à python 3. Ma solution est très simple:

'uid': user.pk,

- je recevoir uidb64 sur mon activer la fonction:

user = User.objects.get(pk=uidb64)

et voila:

Content-Transfer-Encoding: 7bit
Subject: Activate Your MySite Account
From: webmaster@localhost
To: testuser@yahoo.com
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, il fonctionne très bien. :)

1voto

Joe4Jesus Points 11

Je l'ai fait en n'encodant la sortie qu'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 la sortie (impression ou écriture) uniquement.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X