"For line in ..." da como resultado UnicodeDecodeError: el códec 'utf-8' no puede decodificar el byte

214

Aquí está mi código

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

cada vez que ejecuto este código me da el siguiente error:

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

Intenté resolver esto y agregar un parámetro adicional en open (), el código se ve así;

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

Pero nuevamente da el mismo error. ¡que debería hacer entonces! Por favor ayuda.

Sujitos
fuente
3
Datos mal codificados, supongo.
Andreas Jung el
99
O simplemente no datos UTF-8.
Mark Tolonen
Tuvimos este error con msgpack cuando usamos python 3 en lugar de python 2.7. Para nosotros, el curso de acción fue trabajar con Python 2.7.
Jesse W. Collins

Respuestas:

402

Como sugirió Mark Ransom, encontré la codificación correcta para ese problema. La codificación era "ISO-8859-1", por lo que reemplazar open("u.item", encoding="utf-8")con open('u.item', encoding = "ISO-8859-1")va a resolver el problema.

Sujitos
fuente
8
Explícito es mejor que implícito (PEP 20).
Ioannis Filippidis
66
El truco es que ISO-8859-1 o Latin_1 son juegos de caracteres de 8 bits, por lo que toda la basura tiene un valor válido. Quizás no sea utilizable, ¡pero si quieres ignorarlo!
Kjeld Flarup
1
Tuve el mismo problema UnicodeDecodeError: el códec 'utf-8' no puede decodificar el byte 0xd0 en la posición 32: byte de continuación no válido. Usé Python 3.6.5 para instalar aws cli. Y cuando probé aws --version falló con este error. Así que tuve que editar /Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/configparser.py y cambié el código a la siguiente lectura def (self, nombres de archivo, codificación = "ISO-8859-1" ):
Евгений Коптюбенко
3
¿Existe una forma automática de detectar la codificación?
OrangeSherbet
55
@OrangeSherbet Implementé la detección usando chardet. Aquí está la de una sola línea (después import chardet): chardet.detect(open(in_file, 'rb').read())['encoding']. Mira esta respuesta para más detalles: stackoverflow.com/a/3323810/615422
VertigoRay
51

También funcionó para mí, ISO 8859-1 va a ahorrar mucho, jajaja, principalmente si se usan las API de reconocimiento de voz

Ejemplo:

file = open('../Resources/' + filename, 'r', encoding="ISO-8859-1");
Ryoji Kuwae Neto
fuente
44
Puede tener razón en que el OP está leyendo ISO 8859-1, como se puede deducir del 0xe9 (é) en el mensaje de error, pero debe explicar por qué funciona su solución. La referencia a las API de reconocimiento de voz no ayuda.
RolfBly
55
¿Qué pasa con el punto y coma?
Pierna derecha el
29

Su archivo en realidad no contiene datos codificados utf-8, contiene alguna otra codificación. Averigua cuál es esa codificación y úsala en la openllamada.

En Windows-1252, por ejemplo, la codificación 0xe9sería el carácter é.

Mark Ransom
fuente
44
Entonces, ¿cómo puedo averiguar qué codificación es? Estoy usando Linux
SujitS
44
No hay forma de hacer eso que siempre funciona, pero vea la respuesta a esta pregunta: stackoverflow.com/questions/436220/…
RemcoGerlich
20

Prueba esto para leer usando pandas

pd.read_csv('u.item', sep='|', names=m_cols , encoding='latin-1')
Shashank
fuente
No estoy seguro de por qué estás sugiriendo pandas. La solución es configurar la codificación correcta, que has encontrado aquí.
Alastair McCormack
12

Si está utilizando Python 2lo siguiente será la solución:

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

Como el encodingparámetro no funciona open(), recibirá el siguiente error:

TypeError: 'codificación' es un argumento de palabra clave no válido para esta función
Jeril
fuente
1
Pero esta es la versión 3
SujitS
1
Si lo se. Pensé que podría ser útil para las personas que usanPython 2
Jeril
Trabajado para mí en python3 así
fenkerbb
2
En caso de que quieras algo más fácil de recordar, 'ISO-8859-1'también se conoce como 'latin-1'o 'latin1'.
Max Candocia el
9

Podrías resolver el problema con:

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

'rb' está leyendo el archivo en modo binario. Lee más aquí . Espero que esto ayude!

Ozcar Nguyen
fuente
6

Esto funciona:

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

o:

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

Si alguien busca estos, este es un ejemplo para convertir un archivo CSV en Python 3:

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

A veces, cuando open(filepath)en filepathrealidad no hay un archivo, se obtiene el mismo error, así que primero asegúrate de que el archivo que intentas abrir existe:

import os
assert os.path.isfile(filepath)

Espero que esto ayude.

xtluo
fuente
1

puedes intentarlo de esta manera:

open('u.item', encoding='utf8', errors='ignore')
FaridLU
fuente
Esto no proporciona una respuesta a la pregunta. Para criticar o solicitar una aclaración de un autor, deje un comentario debajo de su publicación. - De la opinión
MartenCatcher