如何摆脱python中字符串中的b前缀?


87

我导入的一堆推文在阅读时出现了这个问题

b'I posted a new photo to Facebook'

我收集b表明它是一个字节。但这被证明是有问题的,因为在我最终编写的CSV文件中,该文件b不会消失并且会干扰将来的代码。

有没有简单的方法可以b从我的文字行中删除此前缀?

请记住,我似乎需要将文本编码为utf-8或tweepy难以将其从网络上提取。


这是我正在分析的链接内容:

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

new_tweets = 'content in the link'

代码尝试

outtweets = [[tweet.text.encode("utf-8").decode("utf-8")] for tweet in new_tweets]
print(outtweets)

错误

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>

您能否显示这些文本行的至少一部分?
RomanPerekhrest

@RomanPerekhrest对不起,您还想要什么?代码还是输出?
Stan Shunpike '17

打开文件时始终指定编码。
MKesper '17年

Answers:


136

您需要解码所需bytes的字符串:

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

我已经更新了问题。我认为这种方法行不通。如果可以,您能否详细说明原因?
Stan Shunpike '01

4
.encode("utf-8").decode("utf-8")绝对不做任何事情(如果它可以工作的话)...您使用的是python 3,对吗?py3与bytes和之间有很强的区别str。您的代码中的某些内容似乎使用了cp1252编码...您可以尝试使用打开文件,open(..., mode='w', encoding='utf-8')仅写入str文件;或者您忘记了所有编码,而是以二进制形式写入文件:( open(..., mode='wb')请注意b),仅写入bytes。有帮助吗?
hiro主角,

不,那不能解决。我知道了"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'"
Stan Shunpike '17

您如何分辨它编码为cp1252?我也不认为.encode("utf-8").decode("utf-8")会做任何事情,但是这里的人们似乎认为这是正确的答案,据我所知,这还不算什么。
Stan Shunpike '17

我在您的回溯中发现了这条路径:C:\Users\Stan Shunpike\Anaconda3\lib\encodings\cp1252.py。您可能应该尝试找出使用方式/位置。哦,您正在使用csv.writer; 在这种情况下,您str确实需要写一个not bytes。你从那里得到东西requests吗?您从网络资源获得的编码可能与有所不同utf-8
hiro主角

19

只是让您知道要打印的对象不是字符串,而是字节对象(作为字节常量)。人们用不完整的方式解释了这一点,这就是我的看法。

考虑通过键入字节文字来创建字节对象(从字面上定义字节对象,而无需实际使用字节对象,例如通过键入b''),然后将其转换为以utf-8编码的字符串对象。(请注意,此处转换意味着解码

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

您会看到我们只是应用了该.decode(utf8)功能。

Python中的字节

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

字符串文字由以下词汇定义描述:

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>

5

您需要对其进行解码以将其转换为字符串。在python3中检查有关字节字面量的答案 。

In [1]: b'I posted a new photo to Facebook'.decode('utf-8')
Out[1]: 'I posted a new photo to Facebook'

1
问题是,当我尝试下载tweets而没有encode("utf-8")错误时。而且,正如我在这里提到的,删除stackoverflow.com/q/41915383/4422095并不能解决问题。即使我按照您的建议使用解码,仍然会出现错误。我将其张贴在帖子中。
Stan Shunpike '17

完成。这并不完全相同,因为您需要使用Twitter OAuth代码进行此操作。但是,如果您只是按照我给出的示例进行操作,则会遇到同样的问题。它不是由您建议的方法解决的。它只是撤消utf-8。但这不起作用,因为如果没有utf-8编码,它将无法处理推文中的字符
Stan Shunpike

您必须使用正确的课程编码。 utf-8是一个例子。
salmanwahed


2

在具有django 2.0的python 3.6上,对字节文字进行解码无法按预期进行。是的,我在打印时得到正确的结果,但是即使正确打印,b'value'仍然存在。

这就是即时通讯编码

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

这就是即时解码:

uid = force_text(urlsafe_base64_decode(uidb64))

这就是django 2.0所说的:

urlsafe_base64_encode(s)[source]

在base64中编码一个字节字符串以供URL使用,并去除所有结尾的等号。

urlsafe_base64_decode(s)[source]

解码base64编码的字符串,并添加所有可能已被剥离的尾随等号。


这是我的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 %}

这是我的控制台响应:

内容类型:文本/纯文本;charset =“ utf-8” MIME版本:1.0内容传输编码:7bit主题:激活您的MySite帐户来自:webmaster @ localhost到:testuser@yahoo.com日期:2018年4月20日,星期五06:26:46- 0000消息ID:<152420560682.16725.4597194169307598579@Dash-U>

嗨,testuser,

请点击下面的链接以确认您的注册:

http://127.0.0.1:8000/activate/b'MjU'/4vi-fasdtRf2db2989413ba/

如你看到的 uid = b'MjU'

预期 uid = MjU


在控制台中测试:

$ 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
>>> 

经过调查,它似乎与python 3有关。我的解决方法非常简单:

'uid': user.pk,

我在我的激活函数中以uidb64的形式收到它:

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

和瞧:

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/

现在工作正常。:)


我相信问题不是解码,而是模板中的自动转义,无法像解码一样将字节文字剥离为字符串。
Fernando D Jaime

1

我仅通过使用utf-8编码输出来完成此操作。这是代码示例

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)

即:从api收集数据时不进行编码,仅对输出(打印或写入)进行编码。


0

假设您不想像其他人在这里建议的那样立即再次对其进行解码,则可以将其解析为字符串,然后仅剥离前导'b和尾随'

>>> 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"   

-2

尽管这个问题很老,但我认为这可能对谁面临同样的问题有所帮助。这里的文本是一个字符串,如下所示:

text= "b'I posted a new photo to Facebook'"

因此,您不能通过对b进行编码来删除它,因为它不是一个字节。我做了以下删除它。

cleaned_text = text.split("b'")[1]

这将给 "I posted a new photo to Facebook"


3
不,那会给"I posted a new photo to Facebook'"。无论如何,这不是问题所在。
Tripleee '18
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.