Python CSV-fout: regel bevat NULL-byte

Ik werk met enkele CSV-bestanden, met de volgende code:

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

En één bestand geeft deze fout:

file my.csv, line 1: line contains NULL byte

Wat kan ik doen? Google lijkt te suggereren dat het een Excel-bestand kan zijn dat onjuist is opgeslagen als .csv. Is er een manier om dit probleem in Python te omzeilen?

== BIJWERKEN ==

Na de opmerking van @JohnMachin hieronder, heb ik geprobeerd deze regels aan mijn script toe te voegen:

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')

En dit is de output die ik kreeg:

'\xd0\xcf\x11\xe0\xa1\xb1\x1a\xe1\x00\x00\x00\x00\x00\x00\x00\x00\ .... <snip>
8
13834

Het bestand bevat dus inderdaad NUL bytes.


Antwoord 1, autoriteit 100%

Zoals @S.Lott zegt, zou je je bestanden in ‘rb’-modus moeten openen, niet in ‘rU’-modus. Maar dat kan uw huidige probleem NIET veroorzaken. Voor zover ik weet, zou het gebruik van de ‘rU’-modus je in de war brengen als er \rin de gegevens is ingesloten, maar geen andere drama’s veroorzaken. Ik merk ook op dat je verschillende bestanden hebt (allemaal geopend met ‘rU’ ??) maar slechts één veroorzaakt een probleem.

Als de csv-module zegt dat je een “NULL” (dom bericht, zou “NUL” moeten zijn) byte in je bestand hebben, dan moet je kijken wat er in je bestand staat. Ik stel voor dat je dit doet, zelfs als het gebruik van ‘rb’ ervoor zorgt dat het probleem verdwijnt.

repr()is (of wil zijn) je foutopsporingsvriend. Het zal ondubbelzinnig laten zien wat je hebt, op een platformonafhankelijke manier (wat handig is voor helpers die niet weten wat odis of doet). Doe dit:

print repr(open('my.csv', 'rb').read(200)) # dump 1st 200 bytes of file

en kopieer/plak het resultaat voorzichtig (niet opnieuw typen) in een bewerking van uw vraag (niet in een opmerking).

Houd er ook rekening mee dat als het bestand echt onbetrouwbaar is, b.v. nee \r of \n binnen redelijke afstand vanaf het begin van het bestand, zal het regelnummer gerapporteerd door reader.line_num(onbehulpzaam) zijn 1. Zoek waar de eerste \x00is (indien aanwezig) door te doen

data = open('my.csv', 'rb').read()
print data.find('\x00')

en zorg ervoor dat je minstens zoveel bytes dumpt met repr of od.

Wat vertelt data.count('\x00')u? Als er veel zijn, wil je misschien iets doen als

for i, c in enumerate(data):
    if c == '\x00':
        print i, repr(data[i-30:i]) + ' *NUL* ' + repr(data[i+1:i+31])

zodat u de NUL-bytes in context kunt zien.

Als je \x00in de uitvoer kunt zien (of \0in je od -cuitvoer), dan heb je zeker NUL byte(s) in het bestand, en je moet zoiets als dit doen:

fi = open('my.csv', 'rb')
data = fi.read()
fi.close()
fo = open('mynew.csv', 'wb')
fo.write(data.replace('\x00', ''))
fo.close()

Trouwens, heb je het bestand (inclusief de laatste paar regels) bekeken met een teksteditor? Ziet het er eigenlijk uit als een redelijk CSV-bestand zoals de andere (geen “NULL byte”-uitzondering) bestanden?


Antwoord 2, autoriteit 23%

data_initial = open("staff.csv", "rb")
data = csv.reader((line.replace('\0','') for line in data_initial), delimiter=",")

Dit werkt voor mij.


Antwoord 3, autoriteit 19%

Het lezen als UTF-16 was ook mijn probleem.

Hier is mijn code die uiteindelijk werkte:

f=codecs.open(location,"rb","utf-16")
csvread=csv.reader(f,delimiter='\t')
csvread.next()
for row in csvread:
    print row

Waar locatie de map is van uw csv-bestand.


Antwoord 4, autoriteit 12%

Ik kwam dit probleem ook tegen. Met behulp van de Python csv-module probeerde ik een XLS-bestand te lezen dat in MS Excel was gemaakt en waarbij ik de NULL byte-fout tegenkwam. Ik keek rond en vond de xlrdPython-module voor het lezen en opmaken van gegevens uit MS Excel-spreadsheetbestanden. Met de module xlrdkan ik niet alleen het bestand goed lezen, maar heb ik ook toegang tot veel verschillende delen van het bestand op een manier die voorheen niet mogelijk was.

Ik dacht dat het je misschien zou helpen.


Antwoord 5, autoriteit 12%

U kunt gewoon een generator inlijnen om de nulwaarden uit te filteren als u wilt doen alsof ze niet bestaan. Natuurlijk gaat het ervan uit dat de nul-bytes niet echt deel uitmaken van de codering en echt een soort van onjuist artefact of bug zijn.

with open(filepath, "rb") as f:
    reader = csv.reader( (line.replace('\0','') for line in f) )
    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))

Antwoord 6, Autoriteit 10%

Het converteren van de codering van het bronbestand van UTF-16 naar UTF-8 LOOP MIJN PROBLEEM.

Hoe een bestand om te zetten naar UTF-8 in Python?

import codecs
BLOCKSIZE = 1048576 # or some other, desired size in bytes
with codecs.open(sourceFileName, "r", "utf-16") as sourceFile:
    with codecs.open(targetFileName, "w", "utf-8") as targetFile:
        while True:
            contents = sourceFile.read(BLOCKSIZE)
            if not contents:
                break
            targetFile.write(contents)

Antwoord 7, Autoriteit 2%

Waarom doe je dit?

reader = csv.reader(open(filepath, "rU"))

De documenten zijn vrij duidelijk dat u dit moet doen:

with open(filepath, "rb") as src:
    reader= csv.reader( src )

De modus moet “RB” zijn om te lezen.

http://docs.python.org/library/csv.html# csv.lezer

Als csvfile een bestandsobject is, moet het worden geopend met de ‘b’-vlag op platforms waar dat een verschil maakt.


Antwoord 8, autoriteit 2%

blijkbaar is het een XLS-bestand en geen CSV-bestand zoals http://www.garykessler.net /library/file_sigs.htmlbevestigen


Antwoord 9, autoriteit 2%

In plaats van csv-lezer gebruik ik leesbestand en splitsfunctie voor string:

lines = open(input_file,'rb') 
for line_all in lines:
    line=line_all.replace('\x00', '').split(";")

Antwoord 10

Ik kreeg dezelfde fout. Het bestand opgeslagen in UTF-8 en het werkte.


Antwoord 11

Dit overkwam mij toen ik een CSV-bestand maakte met OpenOffice Calc. Het gebeurde niet toen ik het CSV-bestand in mijn teksteditor maakte, zelfs niet als ik het later met Calc bewerkte.

Ik heb mijn probleem opgelost door de gegevens van mijn door Calc gemaakte bestand in mijn teksteditor te kopiëren en plakken naar een nieuw door de editor gemaakt bestand.


Antwoord 12

Ik had hetzelfde probleem bij het openen van een CSV die was geproduceerd door een webservice die NULL-bytes in lege headers had ingevoegd. Ik heb het volgende gedaan om het bestand op te schonen:

with codecs.open ('my.csv', 'rb', 'utf-8') as myfile:
    data = myfile.read()
    # clean file first if dirty
    if data.count( '\x00' ):
        print 'Cleaning...'
        with codecs.open('my.csv.tmp', 'w', 'utf-8') as of:
            for line in data:
                of.write(line.replace('\x00', ''))
        shutil.move( 'my.csv.tmp', 'my.csv' )
with codecs.open ('my.csv', 'rb', 'utf-8') as myfile:
    myreader = csv.reader(myfile, delimiter=',')
    # Continue with your business logic here...

Disclaimer:
Houd er rekening mee dat dit uw oorspronkelijke gegevens overschrijft. Zorg ervoor dat u er een reservekopie van heeft. Je bent gewaarschuwd!


Antwoord 13

Voor al die ‘rU’ filemode haters: ik heb net geprobeerd een CSV-bestand te openen vanaf een Windows-machine op een Mac met de ‘rb’ filemode en ik kreeg deze foutmelding van de csv-module:

Error: new-line character seen in unquoted field - do you need to 
open the file in universal-newline mode?

Het openen van het bestand in ‘rU’-modus werkt prima. Ik ben dol op de universele nieuwe regelmodus — het bespaart me zoveel gedoe.


Antwoord 14

Ik kwam dit tegen toen ik scrapy gebruikte en een gecomprimeerd csv-bestand ophaalde zonder de juiste middleware te hebben om de antwoordtekst uit te pakken voordat ik het aan de csvreader overhandigde. Daarom was het bestand niet echt een csv-bestand en gooide de line contains NULL byte-fout dienovereenkomstig.


Antwoord 15

Heb je gzip.open geprobeerd?

with gzip.open('my.csv', 'rb') as data_file:

Ik probeerde een bestand te openen dat was gecomprimeerd maar de extensie ‘.csv’ had in plaats van ‘csv.gz’. Deze fout bleef verschijnen totdat ik gzip.open gebruikte


Antwoord 16

Eén geval is dat – Als het CSV-bestand lege rijen bevat, kan deze fout verschijnen. Controleer op rij is nodig voordat we verder gaan met schrijven of lezen.

for row in csvreader:
        if (row):       
            do something

Ik heb mijn probleem opgelost door deze controle in de code toe te voegen.

Other episodes