UnicodeDecodeError,无效的继续字节


257

为什么以下项目失败?为什么使用“ latin-1”编解码器成功?

o = "a test of \xe9 char" #I want this to remain a string as this is what I am receiving
v = o.decode("utf-8")

结果是:

 Traceback (most recent call last):  
 File "<stdin>", line 1, in <module>  
 File "C:\Python27\lib\encodings\utf_8.py",
 line 16, in decode
     return codecs.utf_8_decode(input, errors, True) UnicodeDecodeError:
 'utf8' codec can't decode byte 0xe9 in position 10: invalid continuation byte

Answers:


247

在二进制文件中,0xE9看起来像1110 1001。如果您在Wikipedia上读到有关UTF-8的信息,您会看到这样的字节必须后面跟两个格式10xx xxxx。因此,例如:

>>> b'\xe9\x80\x80'.decode('utf-8')
u'\u9000'

但这仅仅是造成异常的机械原因。在这种情况下,您几乎可以肯定用拉丁文1编码了一个字符串。您可以看到UTF-8和拉丁文1看起来如何不同:

>>> u'\xe9'.encode('utf-8')
b'\xc3\xa9'
>>> u'\xe9'.encode('latin-1')
b'\xe9'

(请注意,我在这里混合使用了Python 2和3表示形式。输入在任何版本的Python中均有效,但是您的Python解释器不太可能以此方式同时显示unicode和字节字符串。)


2
感谢(以及其他回答),我错误地认为直到255的字符都可以直接转换。
RuiDC 2011年

我得到UnicodeEncodeError: 'ascii' codec can't encode characters in position 2-3: ordinal not in range(128)使用错误.encode(latin-1)
湿婆

234

当我尝试通过pandas read_csv方法打开一个csv文件时遇到了相同的错误。

解决方案是将编码更改为“ latin-1”:

pd.read_csv('ml-100k/u.item', sep='|', names=m_cols , encoding='latin-1')

1
这是否真的解决了问题?它基本上不是只是通过降级为不太复杂的编码样式来告诉熊猫忽略该字节吗?
于晨

61

它是无效的UTF-8。该字符是ISO-Latin1中的e-急性字符,这就是它在该代码集中成功的原因。

如果您不知道要在其中接收字符串的代码集,则可能会遇到麻烦。最好为协议/应用程序选择单个代码集(希望是UTF-8),然后拒绝那些未解码的代码集。

如果无法做到这一点,则需要启发式。


2
有关启发式方法,请参见chardet库。
mlissner

44

因为UTF-8是多字节的,并且没有与\xe9加号后跟空格的组合相对应的char 。

为什么要在utf-8和latin-1 中成功?

在utf-8中,这句话应该是这样的:

>>> o.decode('latin-1').encode("utf-8")
'a test of \xc3\xa9 char'

Latin-1是一个单字节编码系列,因此其中的所有内容都应在UTF-8中定义。但是为什么有时候拉丁文1获胜呢?
Reihan_amn

11

如果在处理刚刚打开的文件时出现此错误,请检查是否以'rb'模式打开了该文件。


2
多亏了这个答案,才能够避免UnicodeDecodeError的错误 :'utf-8'编解码器无法解码位置2024079中的字节0xd7:无效的继续字节 by soup = BeautifulSoup(open('webpage.html', 'rb'), 'html.parser')
Isaac Philip

6

当我从.txt文件中读取包含希伯来语的文本时,这也发生在我身上。

我单击: file -> save as并且我将此文件保存为UTF-8编码


5

当数值范围超出0到127时,通常会发生utf-8代码错误。

引发此异常的原因是:

1)如果代码点<128,则每个字节与代码点的值相同。2)如果代码点为128或更大,则无法使用此编码表示Unicode字符串。(在这种情况下,Python引发UnicodeEncodeError异常。)

为了克服这个问题,我们提供了一组编码,使用最广泛的是“ Latin-1,也称为ISO-8859-1”

因此,ISO-8859-1 Unicode点0–255与Latin-1值相同,因此转换为这种编码只需要将代码点转换为字节值即可。如果遇到大于255的代码点,则无法将字符串编码为Latin-1

当您尝试加载数据集时发生此异常时,请尝试使用此格式

df=pd.read_csv("top50.csv",encoding='ISO-8859-1')

在语法末尾添加编码技术,然后接受加载数据集。


嗨,欢迎来到!请编辑您的答案,以确保它可以改善此问题中已经存在的其他答案。
hongsy


-1

在这种情况下,我试图执行一个.py来激活path / file.sql。

我的解决方案是将file.sql的编码修改为“不带BOM的UTF-8”,并且可以使用!

您可以使用Notepad ++来实现。

我将保留一部分代码。

/ 代码 /

con = psycopg2.connect(主机= sys.argv [1],端口= sys.argv [2],dbname = sys.argv [3],用户= sys.argv [4],密码= sys.argv [5] )

cursor = con.cursor()sqlfile = open(path,'r')

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.