Estou tentando ler um arquivo CSV com caracteres acentuados com Python (somente caracteres franceses e / ou espanhóis). Com base na documentação do Python 2.5 para o csvreader ( http://docs.python.org/library/csv.html ), criei o seguinte código para ler o arquivo CSV, já que o csvreader oferece suporte apenas para 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 que 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
...
Embora eu tente codificar / decodificar para UTF-8, ainda recebo 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?
python
utf-8
csv
character-encoding
Martin
fonte
fonte
Respostas:
O
.encode
método é aplicado a uma string Unicode para fazer uma string de bytes; mas você está chamando em uma string de bytes em vez ... do jeito errado! Consulte ocodecs
módulo na biblioteca padrão e,codecs.open
em particular, para melhores soluções gerais para a leitura de arquivos de texto codificados em UTF-8. No entanto, para ocsv
módulo em particular, você precisa passar dados utf-8, e é isso que você já está recebendo, então seu código pode ser muito mais simples:PS: se descobrir que seus dados de entrada NÃO estão em utf-8, mas, por exemplo, em ISO-8859-1, você precisa de uma "transcodificação" (se estiver interessado em usar utf-8 no
csv
nível do módulo) , da formaline.decode('whateverweirdcodec').encode('utf-8')
- mas provavelmente você pode apenas usar o nome de sua codificação existente nayield
linha em meu código acima, em vez de'utf-8'
, comocsv
na verdade vai ficar bem com bytestrings codificados por ISO-8859- *.fonte
Python 2.X
Existe uma biblioteca unicode-csv que deve resolver seus problemas, com o benefício adicional de não navegar para escrever nenhum novo código relacionado ao csv.
Aqui está um exemplo do readme:
Python 3.X
No python 3, isso é compatível com o
csv
módulo integrado. Veja este exemplo:fonte
Se você quiser ler um arquivo CSV com codificação utf-8, uma abordagem minimalista que recomendo é usar algo assim:
Com essa declaração, você pode usar mais tarde um leitor CSV para trabalhar.
fonte
encoding
inopen
open('file.csv', 'r', encoding="ISO8859")
Verifique também a resposta nesta postagem: https://stackoverflow.com/a/9347871/1338557
Ele sugere o uso de uma biblioteca chamada ucsv.py. Substituição curta e simples para CSV escrito para resolver o problema de codificação (utf-8) para Python 2.7. Também oferece suporte para csv.DictReader
Editar : Adicionando código de amostra que usei:
fonte
Usar o
codecs.open
que Alex Martelli sugeriu provou ser útil para mim.fonte
csv
módulo, mas não o usa.O link para a página de ajuda é o mesmo para o python 2.6 e, pelo que eu sei, não houve nenhuma mudança no módulo csv desde o 2.5 (além das correções de bugs). Aqui está o código que simplesmente funciona sem qualquer codificação / decodificação (o arquivo da.csv contém os mesmos dados que os dados variáveis ). Presumo que seu arquivo deve ser lido corretamente sem quaisquer conversões.
test.py:
da.csv:
fonte
delimiter=','
vez dedialect=csv.excel
.É importante notar que, se nada funcionou para você, pode ter esquecido de escapar do seu caminho.
Por exemplo, este código:
Resultaria em um erro:
Para corrigir, basta fazer:
fonte
Olhando para a
Latin-1
tabela Unicode , vejo o código de caractere00E9
" LATIN SMALL LETTER E WITH AGUTE ". Este é o caractere acentuado em seus dados de amostra. Um teste simplesPython
mostra que aUTF-8
codificação para esse caractere é diferente daUTF-16
codificação (quase ) unicode .Eu sugiro que você tente
encode("UTF-8")
os dados Unicode antes de chamar o especialunicode_csv_reader()
. A simples leitura dos dados de um arquivo pode ocultar a codificação, portanto, verifique os valores reais dos caracteres.fonte
Tive o mesmo problema em outro servidor, mas percebi que os locais estão bagunçados.
consertou o problema
fonte