«Pour l'entrée de ligne…» entraîne UnicodeDecodeError: le codec «utf-8» ne peut pas décoder l'octet

217

Voici mon code,

for line in open('u.item'):
#read each line

chaque fois que j'exécute ce code, il donne l'erreur suivante:

UnicodeDecodeError: 'utf-8' codec can't decode byte 0xe9 in position 2892: invalid continuation byte

J'ai essayé de résoudre ce problème et d'ajouter un paramètre supplémentaire dans open (), le code ressemble;

for line in open('u.item', encoding='utf-8'):
#read each line

Mais encore une fois, cela donne la même erreur. que dois-je faire alors! Veuillez aider.

SujitS
la source
3
Des données mal encodées, je suppose.
Andreas Jung
9
Ou tout simplement pas de données UTF-8.
Mark Tolonen
Copie
tripleee
Nous avons eu cette erreur avec msgpack lors de l'utilisation de python 3 au lieu de python 2.7. Pour nous, le plan d'action était de travailler avec python 2.7.
Jesse W. Collins

Réponses:

407

Comme suggéré par Mark Ransom, j'ai trouvé le bon encodage pour ce problème. L'encodage était "ISO-8859-1", donc le remplacer open("u.item", encoding="utf-8")par open('u.item', encoding = "ISO-8859-1")résoudra le problème.

SujitS
la source
8
Explicite vaut mieux qu'implicite (PEP 20).
Ioannis Filippidis
6
L'astuce est que ISO-8859-1 ou Latin_1 est des jeux de caractères 8 bits, donc toutes les ordures ont une valeur valide. Peut-être pas utilisable, mais si vous voulez l'ignorer!
Kjeld Flarup
1
J'ai eu le même problème UnicodeDecodeError: le codec 'utf-8' ne peut pas décoder l'octet 0xd0 en position 32: octet de continuation invalide. J'ai utilisé python 3.6.5 pour installer aws cli. Et quand j'ai essayé aws --version, il a échoué avec cette erreur. J'ai donc dû éditer /Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/configparser.py et changé le code en lecture par
Евгений Коптюбенко
3
Existe-t-il un moyen automatique de détecter l'encodage?
OrangeSherbet
5
@OrangeSherbet J'ai implémenté la détection à l'aide de chardet. Voici le one-liner (après import chardet): chardet.detect(open(in_file, 'rb').read())['encoding']. Consultez cette réponse pour plus de détails: stackoverflow.com/a/3323810/615422
VertigoRay
51

A également fonctionné pour moi, ISO 8859-1 va économiser beaucoup, hahaha, principalement si vous utilisez les API de reconnaissance vocale

Exemple:

file = open('../Resources/' + filename, 'r', encoding="ISO-8859-1");
Ryoji Kuwae Neto
la source
4
Vous avez peut-être raison de dire que l'OP lit ISO 8859-1, comme cela peut être déduit de 0xe9 (é) dans le message d'erreur, mais vous devez expliquer pourquoi votre solution fonctionne. La référence aux API de reconnaissance vocale n'aide pas.
RolfBly
5
Quel est le point-virgule?
Jambe droite
29

Votre fichier ne contient pas réellement de données encodées en utf-8, il contient un autre encodage. Découvrez ce qu'est cet encodage et utilisez-le dans l' openappel.

Dans le codage Windows-1252 par exemple, le 0xe9serait le caractère é.

Mark Ransom
la source
4
Alors, comment savoir de quel encodage il s'agit! J'utilise linux
SujitS
4
Il n'y a aucun moyen de faire cela qui fonctionne toujours, mais voyez la réponse à cette question: stackoverflow.com/questions/436220/…
RemcoGerlich
20

Essayez ceci pour lire en utilisant des pandas

pd.read_csv('u.item', sep='|', names=m_cols , encoding='latin-1')
Shashank
la source
Je ne sais pas pourquoi vous proposez des pandas. La solution consiste à définir le codage correct, que vous avez trouvé ici.
Alastair McCormack
12

Si vous utilisez Python 2ce qui suit la solution:

import io
for line in io.open("u.item", encoding="ISO-8859-1"):
    # do something

Parce que le encodingparamètre ne fonctionne pas avec open(), vous obtiendrez l'erreur suivante:

TypeError: 'encoding' est un argument de mot clé non valide pour cette fonction
Jeril
la source
1
Mais ceci est la version 3
SujitS
1
Ouais je sais. Je pensais que cela pourrait être utile pour les personnes utilisantPython 2
Jeril
A également fonctionné pour moi en Python3
fenkerbb
2
Dans le cas où vous voulez quelque chose de plus facile à retenir, 'ISO-8859-1'est également appelé 'latin-1'ou 'latin1'.
Max Candocia
10

Vous pouvez résoudre le problème avec:

for line in open(your_file_path, 'rb'):

'rb' lit un fichier en mode binaire. Lisez plus ici . J'espère que cela vous aidera!

Ozcar Nguyen
la source
6

Cela marche:

open('filename', encoding='latin-1')

ou:

open('filename',encoding="IS0-8859-1")
Ayesha Siddiqa
la source
2

Si quelqu'un les recherche, voici un exemple de conversion d'un fichier CSV en Python 3:

try:
    inputReader = csv.reader(open(argv[1], encoding='ISO-8859-1'), delimiter=',',quotechar='"')
except IOError:
    pass
user6832484
la source
2

Parfois, lorsque open(filepath)ce filepathn'est pas le cas, un fichier obtiendrait la même erreur, alors assurez-vous d'abord que le fichier que vous essayez d'ouvrir existe:

import os
assert os.path.isfile(filepath)

j'espère que cela vous aidera.

xtluo
la source
1

vous pouvez essayer de cette façon:

open('u.item', encoding='utf8', errors='ignore')
FaridLU
la source
Cela ne fournit pas de réponse à la question. Pour critiquer ou demander des éclaircissements à un auteur, laissez un commentaire sous son article. - De l'avis
MartenCatcher