Вопрос-Ответ

UnicodeDecodeError, invalid continuation byte

Ошибка UnicodeDecodeError, недопустимый байт продолжения

Почему не удается выполнить приведенный ниже элемент? Почему это удается с кодеком "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
Переведено автоматически
Ответ 1

У меня была такая же ошибка, когда я пытался открыть CSV-файл с помощью pandas.read_csv метода.

Решением было изменить кодировку на latin-1:

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

В двоичном формате 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 вряд ли действительно будет отображать как юникод, так и байтовые строки таким образом.)

Ответ 3

Недопустимый UTF-8. Этот символ является символом e-acute в ISO-Latin1, поэтому он выполняется успешно с этим набором кодов.

Если вы не знаете набор кодов, в котором получаете строки, у вас небольшие проблемы. Было бы лучше, если бы для вашего протокола / приложения был выбран единый набор кодов (надеюсь, UTF-8), а затем вы бы просто отвергли те, которые не декодировались.

Если вы не можете этого сделать, вам понадобится эвристика.

Ответ 4

Потому что UTF-8 многобайтовый и в нем нет символа, соответствующего вашей комбинации \xe9 плюс следующий пробел.

Почему он должен быть успешным в обоих utf-8 и latin-1?

Вот как это же предложение должно быть в utf-8:

>>> o.decode('latin-1').encode("utf-8")
'a test of \xc3\xa9 char'
2023-04-28 22:40 python unicode