Lendo um arquivo CSV UTF8 com Python

votos
76

Eu estou tentando ler um arquivo CSV com caracteres acentuados com Python (apenas francês e / ou personagens espanhol). Com base no Python 2.5 documentação para o CSVReader ( http://docs.python.org/library/csv.html ), eu vim com o seguinte código para ler o arquivo CSV desde o CSVReader suporta apenas 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:
        ...

Abaixo está um trecho do arquivo CSV Eu estou tentando ler:

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
...

Mesmo que eu tente para codificar / decodificar a UTF-8, eu ainda estou recebendo a seguinte exceção:

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)

Como faço para corrigir isso?

Publicado 24/05/2009 em 16:56
fonte usuário
Em outras línguas...                            


9 respostas

votos
99

O .encodemétodo é aplicado a uma seqüência de caracteres Unicode para fazer um byte-string; mas você está chamando-o em um byte-string em vez ... o caminho errado 'redondo! Olhe para o codecsmódulo na biblioteca padrão e codecs.open, em particular, para obter melhores soluções gerais para a leitura de arquivos UTF-8 texto codificado. No entanto, para o csvmódulo em particular, você precisa passar em UTF-8 dados, e isso é o que você já está recebendo, por isso, seu código pode ser muito mais simples:

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 

PS: se ele sair que seus dados de entrada não está em utf-8, mas por exemplo, em ISO-8859-1, então você precisa de um "transcodificação" (se você estiver interessado em usar utf-8 no csvnível de módulo) , da forma line.decode('whateverweirdcodec').encode('utf-8')- mas provavelmente você pode simplesmente usar o nome de sua codificação existente na yieldlinha no meu código acima, em vez de 'utf-8', como csvé realmente vai ser muito bem com iso-8859- * bytestrings codificados.

Respondeu 24/05/2009 em 17:14
fonte usuário

votos
49

2.X Python

Há um unicode-csv biblioteca que deve resolver os seus problemas, com vantagem de não naving de escrever qualquer novo código relacionado com o CSV.

Aqui está um exemplo de seu readme:

>>> 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]
é ñ

3.X Python

Em python 3 isto é apoiado fora da caixa pela build-in csvmódulo. Veja este exemplo:

import csv
with open('some.csv', newline='', encoding='utf-8') as f:
    reader = csv.reader(f)
    for row in reader:
        print(row)
Respondeu 09/02/2013 em 10:37
fonte usuário

votos
3

Também verificação geral a resposta neste post: https://stackoverflow.com/a/9347871/1338557

Ele sugere o uso da biblioteca chamada ucsv.py. substituição curto e simples para CSV escrito para resolver o problema de codificação (UTF-8) para Python 2.7. Também fornece suporte para csv.DictReader

Editar : Adicionando código de exemplo que eu usei:

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'])})
Respondeu 17/07/2014 em 03:31
fonte usuário

votos
1

Usando codecs.opencomo Alex Martelli sugeriu provou ser útil para mim.

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 ...
Respondeu 04/01/2013 em 18:53
fonte usuário

votos
1

O link para a página de ajuda é o mesmo para Python 2.6 e, tanto quanto eu sei, não houve mudança no módulo csv desde 2.5 (além de correções de bugs). Aqui está o código que simplesmente funciona sem qualquer codificação / decodificação (da.csv arquivo contém os mesmos dados como a variável de dados ). Presumo que o arquivo deve ser lido corretamente sem qualquer conversão.

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
Respondeu 24/05/2009 em 19:29
fonte usuário

votos
0

Vale notar que, se nada funcionou para você, você pode ter esquecido de escapar de seu caminho.
Por exemplo, este código:

f = open("C:\Some\Path\To\file.csv")

Resultaria em um erro:

SintaxError: (erro Unicode) codec 'unicodeescape' não pode descodificar bytes na posição 2-3: truncado de escape \ UXXXXXXXX

Para corrigir, basta fazer:

f = open("C:\\Some\\Path\\To\\file.csv")
Respondeu 15/10/2019 em 18:58
fonte usuário

votos
0

Teve o mesmo problema em outro servidor, mas percebeu que locais estão bagunçados.

export LC_ALL="en_US.UTF-8"

corrigiu o problema

Respondeu 03/07/2019 em 13:31
fonte usuário

votos
0

Se você quiser ler um arquivo CSV com a codificação utf-8, uma abordagem minimalista que eu recomendo que você é usar algo como isto:

        with open(file_name, encoding="utf8") as csv_file:

Com essa declaração, você pode usar mais tarde um leitor CSV para trabalhar.

Respondeu 15/08/2018 em 21:55
fonte usuário

votos
0

Olhando para o Latin-1mesa unicode , vejo o código de caractere 00E9" latin letra PEQUENA E COM AGUDA ". Este é o caractere acentuado em seus dados de amostra. Um teste simples em Pythonmostra que UTF-8codifica para este carácter é diferente do Unicode (quase UTF-16) codificação.

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

Eu sugiro que você tente encode("UTF-8")os dados Unicode antes de chamar a especial unicode_csv_reader(). Basta ler os dados de um arquivo pode esconder a codificação, de modo a verificar os valores de caracteres reais.

Respondeu 24/05/2009 em 17:54
fonte usuário

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more