Estou trabalhando com alguns arquivos CSV, com o seguinte código:
reader = csv.reader(open(filepath, "rU"))
try:
for row in reader:
print 'Row read successfully!', row
except csv.Error, e:
sys.exit('file %s, line %d: %s' % (filename, reader.line_num, e))
E um arquivo está gerando este erro:
file my.csv, line 1: line contains NULL byte
O que eu posso fazer? O Google parece sugerir que pode ser um arquivo do Excel que foi salvo como .csv indevidamente. Existe alguma maneira de contornar esse problema em Python?
== ATUALIZAÇÃO ==
Seguindo o comentário de @JohnMachin abaixo, tentei adicionar estas linhas ao meu script:
print repr(open(filepath, 'rb').read(200)) # dump 1st 200 bytes of file
data = open(filepath, 'rb').read()
print data.find('\x00')
print data.count('\x00')
E esta é a saída que obtive:
'\xd0\xcf\x11\xe0\xa1\xb1\x1a\xe1\x00\x00\x00\x00\x00\x00\x00\x00\ .... <snip>
8
13834
Portanto, o arquivo realmente contém bytes NUL.
od -c
a aparência da primeira linha?Respostas:
Como @ S.Lott diz, você deve abrir seus arquivos no modo 'rb', não no modo 'rU'. No entanto, isso pode NÃO estar causando o problema atual. Tanto quanto eu sei, usar o modo 'rU' iria confundi-lo se houver
\r
dados incorporados , mas não causaria quaisquer outros dramas. Também observo que você possui vários arquivos (todos abertos com 'rU' ??), mas apenas um está causando o problema.Se o módulo csv diz que você tem um byte "NULL" (mensagem boba, deveria ser "NUL") em seu arquivo, então você precisa verificar o que está em seu arquivo. Eu sugiro que você faça isso mesmo se usar 'rb' resolver o problema.
repr()
é (ou quer ser) seu amigo na depuração. Ele mostrará de forma inequívoca o que você tem, de uma forma independente da plataforma (o que é útil para auxiliares que não sabem o queod
é ou o que faz). Faça isso:e copie / cole cuidadosamente (não digite novamente) o resultado em uma edição de sua pergunta (não em um comentário).
Observe também que se o arquivo for realmente duvidoso, por exemplo, no \ r ou \ n dentro de uma distância razoável do início do arquivo, o número da linha relatado por
reader.line_num
será (inutilmente) 1. Encontre onde está o primeiro\x00
(se houver) fazendoe certifique-se de despejar pelo menos essa quantidade de bytes com repr ou od.
O que
data.count('\x00')
isso te diz? Se houver muitos, você pode querer fazer algo comopara que você possa ver os bytes NUL no contexto.
Se você pode ver
\x00
na saída (ou\0
na suaod -c
saída), então você definitivamente tem byte (s) NUL no arquivo e precisará fazer algo assim:A propósito, você olhou para o arquivo (incluindo as últimas linhas) com um editor de texto? Ele realmente se parece com um arquivo CSV razoável como os outros arquivos (sem exceção de "byte NULL")?
fonte
'\xd0\xcf\x11\xe0\xa1\xb1\x1a\xe1
é a "assinatura" que denota um arquivo de Documento Composto OLE2 - por exemplo, um arquivo .XLS do Excel 97-2003 . Acho que "em um editor de texto parece um arquivo CSV perfeitamente razoável", totalmente inacreditável . Você deve ter olhado um arquivo diferente, um arquivo CSV válido, em outra pasta ou em outra máquina ou em algum outro momento. Observe que suaod
saída não foi de um arquivo XLS.csv.reader
diretamente.fo.write(data.replace('\x00', ''))
serfo.write(data.replace(b'\x00', b''))
? Python 3.6 aqui ...Isso funciona para mim.
fonte
Ler como UTF-16 também foi meu problema.
Este é o meu código que acabou funcionando:
Onde localização é o diretório do seu arquivo csv.
fonte
Também me deparei com esse problema. Usando o
csv
módulo Python , tentei ler um arquivo XLS criado no MS Excel e encontrei oNULL byte
erro que você estava obtendo. Eu olhei ao redor e encontrei o módulo xlrd Python para ler e formatar dados de arquivos de planilha do MS Excel. Com oxlrd
módulo, não só consigo ler o arquivo corretamente, mas também posso acessar muitas partes diferentes do arquivo de uma maneira que não conseguia antes.Achei que poderia te ajudar.
fonte
Converter a codificação do arquivo de origem de UTF-16 para UTF-8 resolve meu problema.
Como converter um arquivo para utf-8 em Python?
fonte
Você poderia apenas embutir um gerador para filtrar os valores nulos se quiser fingir que eles não existem. É claro que isso pressupõe que os bytes nulos não façam parte da codificação e sejam algum tipo de artefato ou bug errôneo.
fonte
Por que você está fazendo isso?
Os documentos são bem claros de que você deve fazer isso:
O modo deve ser "rb" para ler.
http://docs.python.org/library/csv.html#csv.reader
fonte
od
ou olha em um editor de texto, parece um arquivo CSV perfeitamente normal. No entanto, quando ele despeja os primeiros bytes com Python repr (), isso se torna um arquivo .XLS do Excel (que foi renomeado para ter uma extensão CSV).aparentemente é um arquivo XLS e não um arquivo CSV conforme http://www.garykessler.net/library/file_sigs.html confirmar
fonte
Em vez do leitor csv, uso ler arquivo e dividir a função para string:
fonte
Eu tenho o mesmo erro. Salvei o arquivo em UTF-8 e funcionou.
fonte
Isso aconteceu comigo quando criei um arquivo CSV com o OpenOffice Calc. Isso não aconteceu quando criei o arquivo CSV no meu editor de texto, mesmo que mais tarde o tenha editado com o Calc.
Resolvi meu problema copiando e colando no meu editor de texto os dados do meu arquivo criado pelo Calc em um novo arquivo criado pelo editor.
fonte
Eu tive o mesmo problema ao abrir um CSV produzido a partir de um webservice que inseriu bytes NULL em cabeçalhos vazios. Fiz o seguinte para limpar o arquivo:
Isenção de responsabilidade: esteja ciente de que isso substitui seus dados originais. Certifique-se de ter uma cópia de backup dele. Você foi avisado!
fonte
Para todos os inimigos do modo de arquivo 'rU': Acabei de tentar abrir um arquivo CSV de uma máquina Windows em um Mac com o modo de arquivo 'rb' e recebi este erro do módulo csv:
Abrir o arquivo no modo 'rU' funciona bem. Eu amo o modo de nova linha universal - ele me economiza muito trabalho.
fonte
Eu encontrei isso ao usar o scrapy e buscar um csvfile compactado sem ter um middleware correto para descompactar o corpo da resposta antes de entregá-lo ao csvreader. Portanto, o arquivo não era realmente um arquivo csv e gerava o
line contains NULL byte
erro de acordo.fonte
Você já tentou usar gzip.open?
Eu estava tentando abrir um arquivo que havia sido compactado, mas tinha a extensão '.csv' em vez de 'csv.gz'. Esse erro continuou aparecendo até eu usar gzip.open
fonte
Um caso é este - se o arquivo CSV contiver linhas vazias, esse erro pode aparecer. É necessário verificar a linha antes de prosseguir com a escrita ou leitura.
Resolvi meu problema adicionando este cheque no código.
fonte