403 votes

UnicodeDecodeError, octet de continuation invalide

Pourquoi l'élément ci-dessous est-il défaillant ? Pourquoi cela réussit-il avec le codec "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")

Ce qui a pour conséquence :

 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

446voto

Mazen Aly Points 3835

J'ai eu la même erreur lorsque j'ai essayé d'ouvrir un fichier CSV en pandas.read_csv méthode.

La solution a été de changer l'encodage en latin-1 :

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

7 votes

Mais est-ce que cela résout réellement le problème ? Ne dit-on pas simplement à pandas d'ignorer l'octet en passant à un style d'encodage moins complexe ?

1 votes

Fonctionne bien pour l'intégration ouvrir fonction. Merci

331voto

Josh Lee Points 53741

En binaire, 0xE9 se présente comme suit 1110 1001 . Si vous lisez sur UTF-8 sur Wikipedia vous verrez qu'un tel octet doit être suivi de deux autres de la forme 10xx xxxx . Ainsi, par exemple :

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

Mais ce n'est que la cause mécanique de l'exception. Dans ce cas, vous avez une chaîne qui est presque certainement encodée en latin 1. Vous pouvez voir comment UTF-8 et latin 1 sont différents :

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

(Note, j'utilise ici un mélange de représentation de Python 2 et 3. L'entrée est valable dans n'importe quelle version de Python, mais il est peu probable que votre interpréteur Python affiche réellement les chaînes unicode et octet de cette manière).

2 votes

Merci (et aux autres qui ont répondu), je pensais à tort que les caractères jusqu'à 255 seraient directement convertis.

0 votes

Je reçois UnicodeEncodeError: 'ascii' codec can't encode characters in position 2-3: ordinal not in range(128) erreur lors de l'utilisation .encode(latin-1)

71voto

Sami Lehtinen Points 401

C'est un UTF-8 invalide. Ce caractère est le caractère e-acute dans l'ISO-Latin1, c'est pourquoi il réussit avec ce jeu de codes.

Si vous ne connaissez pas le jeu de codes dans lequel vous recevez les chaînes, vous avez des problèmes. Le mieux serait de choisir un seul jeu de codes (avec un peu de chance UTF-8) pour votre protocole/application, puis de rejeter ceux qui ne sont pas décodés.

Si vous ne pouvez pas le faire, vous aurez besoin d'une heuristique.

3 votes

Et pour les heuristiques, voir la bibliothèque chardet.

51voto

neurino Points 3207

Parce que l'UTF-8 est multi-octet et qu'il n'y a pas de caractère correspondant à votre combinaison de caractères \xe9 plus l'espace suivant.

Pourquoi devrait-elle réussir à les deux utf-8 et latin-1 ?

Voici comment la même phrase devrait être en utf-8 :

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

0 votes

Latin-1 est une famille d'encodage à un seul octet, donc tout ce qu'elle contient doit être défini en UTF-8. Mais pourquoi, parfois, le Latin-1 l'emporte-t-il ?

23voto

Patrick Mutuku Points 139

Si cette erreur survient lors de la manipulation d'un fichier qui vient d'être ouvert, vérifiez si vous l'avez ouvert dans le dossier de l'utilisateur. 'rb' mode

4 votes

Grâce à cette réponse, a été en mesure d'éviter l'erreur de, UnicodeDecodeError : Le codec 'utf-8' ne peut pas décoder l'octet 0xd7 en position 2024079 : octet de continuation invalide. par soup = BeautifulSoup(open('webpage.html', 'rb'), 'html.parser')

0 votes

Merci beaucoup !

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