UnicodeDecodeError,无效的继续字节

491 投票
13 回答
1618832 浏览
提问于 2025-04-16 15:07

下面这个项目为什么会失败呢?为什么用“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

13 个回答

77

这不是有效的UTF-8编码。那个字符在ISO-Latin1编码中是个带重音的字母e,所以在使用这种编码时它能正常工作。

如果你不知道你收到的字符串是什么编码,那就有点麻烦了。最好是为你的协议或应用选择一种编码(希望是UTF-8),然后直接拒绝那些无法解码的字符串。

如果你不能这样做,那你就需要一些经验法则来处理了。

562

我在用 pandas.read_csv 方法打开一个 CSV 文件时也遇到了同样的错误。

解决办法是把编码改成 latin-1

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

在二进制中,0xE9看起来像1110 1001。如果你去维基百科上看看关于UTF-8的内容,你会发现这样的字节后面必须跟着两个形状为10xx xxxx的字节。所以,比如说:

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

但这只是导致异常的机械原因。在这个例子中,你有一个字符串,它几乎肯定是用latin 1编码的。你可以看到UTF-8和latin 1的表现是不同的:

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

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

撰写回答