2010-08-13 14 views
10

Estoy leyendo en un archivo con el módulo csv de Python, y tengo otra pregunta de codificación (lo siento, hay tantas aquí).Python csv: UnicodeDecodeError

En el archivo CSV, hay £ signos. Después de leer la fila e imprimirla, se han convertido en \ xa3.

Tratando de codificarlos como Unicode produce una UnicodeDecodeError:

row = [unicode(x.strip()) for x in row] 
UnicodeDecodeError: 'ascii' codec can't decode byte 0xa3 in position 0: ordinal not in range(128) 

He estado leyendo el csv documentation y las numerosas otras preguntas sobre esto en StackOverflow. I piensa que £ ser \ xa3 en ASCII significa que el archivo CSV original está en UTF-8.

(Por cierto, hay una manera rápida de comprobar la codificación de un archivo CSV?)

Si está en UTF-8, entonces no debería el módulo csv ser capaz de hacer frente a ella? Parece que está transformando todos los símbolos en ASCII, aunque la documentación afirma que acepta UTF-8.

He intentado agregar una función unicode_csv_reader como se describe en el csv examples, pero no ayuda.

---- ----- EDITAR

Debo aclarar una cosa. He visto this question, que se ve muy similar. Sin embargo, la adición de la función definida unicode_csv_reader no produce un error diferente en su lugar:

yield [unicode(cell, 'utf-8') for cell in row] 
UnicodeDecodeError: 'utf8' codec can't decode byte 0xa3 in position 8: unexpected code byte 

Así que tal vez mi archivo no es UTF-8, después de todo? ¿Cómo puedo decir?

Respuesta

7

Intente utilizar el "ISO-8859-1" para su codificación. Parece que estás tratando con ASCII extendido, no con Unicode.

Editar:

Aquí hay un código simple que se ocupa de ASCII extendido:

>>> s = "La Pe\xf1a" 
>>> print s 
La Pe±a 
>>> print s.decode("latin-1") 
La Peña 
>>> 

Aún mejor, tratar con el carácter exacto que le está dando problemas:

>>> s = "12\xa3" 
>>> print s.decode("latin-1") 
12£ 
>>> 
+0

Qué quiere decir el uso: el rendimiento [Unicode (célula, 'ISO-8859-1') para celular en fila] en su lugar, en la función unicode_csv_reader? Lamentablemente, eso no ayuda: vuelva al error ordinal no en rango (128) nuevamente. – AP257

+0

No tendría mucho sentido utilizar una función llamada unicode() cuando se trata de ASCII. Lo que estoy diciendo es que está tratando con un archivo que está codificado usando una codificación "ISO-8859-1".No publiqué ningún código, porque no sé cómo hacerlo fuera de mi cabeza, pero tu problema es que debes decodificarlo como ISO-8859-1, no como Unicode. – riwalk

+0

OK, gracias. Voy a investigar. ¿Cómo sabías que era ISO-8859-1? En otras palabras, ¿hay alguna manera de que yo verifique las codificaciones yo mismo, en lugar de solo hacer preguntas estúpidas en StackOverflow :) – AP257

0

Si están en Windows, es muy probable que la codificación que debe usar sea de la familia cp125X ... por ejemplo si se encuentra en Europa occidental o en las Américas, será cp1252. El software de Windows a menudo usa bytes en el rango de \x80 a \x9F inclusive para codificar caracteres de puntuación de lujo, mientras que ese rango está reservado en ISO-8859-X para los "Caracteres de control C1" poco utilizados.

Puede averiguar la codificación habitual en su idioma ejecutando esto en la línea de comandos:

python -c "import locale; print locale.getpreferredencoding()" 
+0

Tiene dificultades para leer £ signos, y está suponiendo que el archivo fue convenientemente guardado en cualquier configuración * su * computadora prefiere? Sería cuidadoso al asumir que el archivo es algo que se guardó usando su máquina. – riwalk

+0

@ Stargazer712: No, no estoy asumiendo nada. Estoy sugiriendo que es muy probable que el archivo se haya creado en una máquina en la misma localidad y usando el mismo sistema operativo que la máquina que está utilizando el OP. –

+0

Mi experiencia con codificaciones (como mencioné anteriormente) vino de raspar la web. Te aseguro que no es una suposición segura. – riwalk