reading leer dictreader create python utf-8 csv character-encoding

leer - Lectura de un archivo CSV UTF8 con Python



save to csv python (6)

Python 2.X

Existe una biblioteca unicode-csv que debería resolver sus problemas, con el beneficio adicional de no escribir ningún código nuevo relacionado con csv.

Aquí hay un ejemplo de su archivo Léame:

>>> import unicodecsv >>> from cStringIO import StringIO >>> f = StringIO() >>> w = unicodecsv.writer(f, encoding=''utf-8'') >>> w.writerow((u''é'', u''ñ'')) >>> f.seek(0) >>> r = unicodecsv.reader(f, encoding=''utf-8'') >>> row = r.next() >>> print row[0], row[1] é ñ

Python 3.X

En python 3, esto es compatible con el módulo de csv incorporado. Mira este ejemplo:

import csv with open(''some.csv'', newline='''', encoding=''utf-8'') as f: reader = csv.reader(f) for row in reader: print(row)

Intento leer un archivo CSV con caracteres acentuados con Python (solo caracteres en francés y / o español). Basado en la documentación de Python 2.5 para csvreader ( http://docs.python.org/library/csv.html ), se me ocurrió el siguiente código para leer el archivo CSV, ya que el csvreader solo admite ASCII.

def unicode_csv_reader(unicode_csv_data, dialect=csv.excel, **kwargs): # csv.py doesn''t do Unicode; encode temporarily as UTF-8: csv_reader = csv.reader(utf_8_encoder(unicode_csv_data), dialect=dialect, **kwargs) for row in csv_reader: # decode UTF-8 back to Unicode, cell by cell: yield [unicode(cell, ''utf-8'') for cell in row] def utf_8_encoder(unicode_csv_data): for line in unicode_csv_data: yield line.encode(''utf-8'') filename = ''output.csv'' reader = unicode_csv_reader(open(filename)) try: products = [] for field1, field2, field3 in reader: ...

A continuación se muestra un extracto del archivo CSV que estoy tratando de leer:

0665000FS10120684,SD1200IS,Appareil photo numérique PowerShot de 10 Mpx de Canon avec trépied (SD1200IS) - Bleu 0665000FS10120689,SD1200IS,Appareil photo numérique PowerShot de 10 Mpx de Canon avec trépied (SD1200IS) - Gris 0665000FS10120687,SD1200IS,Appareil photo numérique PowerShot de 10 Mpx de Canon avec trépied (SD1200IS) - Vert ...

Aunque intento codificar / descodificar a UTF-8, sigo recibiendo la siguiente excepción:

Traceback (most recent call last): File "./Test.py", line 53, in <module> for field1, field2, field3 in reader: File "./Test.py", line 40, in unicode_csv_reader for row in csv_reader: File "./Test.py", line 46, in utf_8_encoder yield line.encode(''utf-8'', ''ignore'') UnicodeDecodeError: ''ascii'' codec can''t decode byte 0xc3 in position 68: ordinal not in range(128)

¿Cómo puedo solucionar esto?


Al mirar la tabla Unicode de Latin-1 , veo el código de carácter 00E9 " LETRA E 00E9 LATINA CON AGUDO ". Este es el carácter acentuado en sus datos de muestra. Una prueba simple en Python muestra que la UTF-8 para este personaje es diferente de la UTF-16 Unicode (casi UTF-16 ).

>>> u''/u00e9'' u''/xe9'' >>> u''/u00e9''.encode(''utf-8'') ''/xc3/xa9'' >>>

Le sugiero que intente encode("UTF-8") los datos Unicode antes de llamar al especial unicode_csv_reader() . Simplemente leyendo los datos de un archivo podría ocultar la codificación, así que verifique los valores de los caracteres reales.


El enlace a la página de ayuda es el mismo para python 2.6 y, por lo que yo sé, no hubo cambios en el módulo csv desde 2.5 (además de las correcciones de errores). Aquí está el código que simplemente funciona sin codificación / descodificación (el archivo da.csv contiene los mismos datos que los datos variables). Supongo que su archivo debe leerse correctamente sin conversiones.

test.py:

## -*- coding: utf-8 -*- # # NOTE: this first line is important for the version b) read from a string(unicode) variable # import csv data = / """0665000FS10120684,SD1200IS,Appareil photo numérique PowerShot de 10 Mpx de Canon avec trépied (SD1200IS) - Bleu 0665000FS10120689,SD1200IS,Appareil photo numérique PowerShot de 10 Mpx de Canon avec trépied (SD1200IS) - Gris 0665000FS10120687,SD1200IS,Appareil photo numérique PowerShot de 10 Mpx de Canon avec trépied (SD1200IS) - Vert""" # a) read from a file print ''reading from a file:'' for (f1, f2, f3) in csv.reader(open(''da.csv''), dialect=csv.excel): print (f1, f2, f3) # b) read from a string(unicode) variable print ''reading from a list of strings:'' reader = csv.reader(data.split(''/n''), dialect=csv.excel) for (f1, f2, f3) in reader: print (f1, f2, f3)

da.csv:

0665000FS10120684,SD1200IS,Appareil photo numérique PowerShot de 10 Mpx de Canon avec trépied (SD1200IS) - Bleu 0665000FS10120689,SD1200IS,Appareil photo numérique PowerShot de 10 Mpx de Canon avec trépied (SD1200IS) - Gris 0665000FS10120687,SD1200IS,Appareil photo numérique PowerShot de 10 Mpx de Canon avec trépied (SD1200IS) - Vert


El método .encode se aplica a una cadena Unicode para crear una cadena de bytes; pero lo estás llamando en una cadena de bytes en cambio ... ¡al revés! Mire el módulo de codecs en la librería estándar y codecs.open en particular para mejores soluciones generales para leer archivos de texto codificados en UTF-8. Sin embargo, para el módulo csv en particular, necesita pasar datos utf-8, y eso es lo que ya está obteniendo, por lo que su código puede ser mucho más simple:

import csv def unicode_csv_reader(utf8_data, dialect=csv.excel, **kwargs): csv_reader = csv.reader(utf8_data, dialect=dialect, **kwargs) for row in csv_reader: yield [unicode(cell, ''utf-8'') for cell in row] filename = ''da.csv'' reader = unicode_csv_reader(open(filename)) for field1, field2, field3 in reader: print field1, field2, field3

PD: si resulta que tus datos de entrada NO están en utf-8, pero por ejemplo en ISO-8859-1, entonces necesitas una "transcodificación" (si estás interesado en usar utf-8 en el nivel de módulo csv ) ), de la forma line.decode(''whateverweirdcodec'').encode(''utf-8'') - pero probablemente solo puedas usar el nombre de tu codificación existente en la línea de yield en mi código anterior, en lugar de ''utf-8'' , ya que csv realmente va a estar bien con ISO-8859- * cadenas de bytes codificadas.


También revise la respuesta en esta publicación: https://.com/a/9347871/1338557

Sugiere el uso de la biblioteca llamada ucsv.py. Reemplazo breve y simple de CSV escrito para abordar el problema de codificación (utf-8) para Python 2.7. También proporciona soporte para csv.DictReader

Editar : Agregar código de muestra que utilicé:

import ucsv as csv #Read CSV file containing the right tags to produce fileObj = open(''awol_title_strings.csv'', ''rb'') dictReader = csv.DictReader(fileObj, fieldnames = [''titles'', ''tags''], delimiter = '','', quotechar = ''"'') #Build a dictionary from the CSV file-> {<string>:<tags to produce>} titleStringsDict = dict() for row in dictReader: titleStringsDict.update({unicode(row[''titles'']):unicode(row[''tags''])})


Usar codecs.open como sugirió Alex Martelli resultó ser útil para mí.

import codecs delimiter = '';'' reader = codecs.open("your_filename.csv", ''r'', encoding=''utf-8'') for line in reader: row = line.split(delimiter) # do something with your row ...