Python CSVエラー:行にNULLバイトが含まれています


102

私は次のコードでいくつかのCSVファイルを操作しています:

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

そして、1つのファイルがこのエラーを投げています:

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

私に何ができる?グーグルはそれが不適切に.csvとして保存されたExcelファイルである可能性があることを示唆しているようです。Pythonでこの問題を回避する方法はありますか?

==更新==

以下の@JohnMachinのコメントに従って、これらの行をスクリプトに追加してみました。

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

そして、これは私が得た出力です:

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

そのため、ファイルには実際にNULバイトが含まれています。


od -c最初の行はどのように表示されますか?
Ignacio Vazquez-Abrams

cat my.csvのようなクエリを実行する必要があります。od -c | もっと ?それで私は得る:0000000 D epartment F amil
AP257 2010

CSVはどのように生成されますか?エクセルから、方言を試すことができるかもしれません。それ以外の場合は発言を見て:stackoverflow.com/questions/2753022/...
DRのjimbob

ありがとう。私のCSVではありません。残念ながら、変更する権限がありません。Excelで作成され、CSV(boo)で保存されていると思います。方言はいい考えのように聞こえます-私はそれを試してみます!
AP257、2010年

実際にCSVとして保存されている場合は、機能するはずです。私が時々見つけることの1つは、CSVになりすましたTSV(タブ区切り)ファイルであるため、区切り文字「\ t」を設定してみてください。Excelファイルとして保存され、拡張子がCSVに変更された場合、方言は機能しません。その場合の唯一の選択肢は、Excelを使用してコピーを適切なCSVとして保存することです。
トーマスK

回答:


104

@ S.Lottが言うように、ファイルは「rU」モードではなく「rb」モードで開く必要があります。ただし、それが現在の問題を引き起こしているわけではありません。私の知る限り、「rU」モードを使用\rすると、データが埋め込まれている場合は混乱しますが、他のドラマは発生しません。また、いくつかのファイル(すべて 'rU'で開かれている??)があることにも注意してください。

csvモジュールが、ファイルに「NULL」(ばかげたメッセージ、「NUL」である必要があります)バイトがあると言った場合、ファイルの内容を確認する必要があります。'rb'を使用して問題が解消されたとしても、これを行うことをお勧めします。

repr()デバッグの友です(またはなりたい)。これは、プラットフォームに依存しない方法で、得られたものを明確に示します(これは、何odが何をしているかを知らないヘルパーに役立ちます)。これを行う:

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

結果を注意深くコピー/貼り付け(再入力しないでください)して、質問の編集(コメントではなく)に貼り付けます。

また、ファイルが本当に危険なの場合はそのノートがないなど、\ rのか、\ nはファイルの先頭から合理的な距離内、行番号がで報告されたreader.line_num最初の(unhelpfully)となります。1.検索\x00実行している(もしあれば)

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

そして、少なくともreprまたはodでそのバイト数をダンプすることを確認してください。

何をdata.count('\x00')教えてくれますか?たくさんある場合、あなたは次のようなことをしたいかもしれません

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

コンテキストでNULバイトを確認できるようにします。

あなたが見ることができる場合\x00(または出力に\0あなたの中od -c出力)、その後、あなたは間違いなくファイルにNULバイト(複数可)を持っている、とあなたはこのような何かをする必要があります。

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

ちなみに、テキストエディタでファイル(最後の数行を含む)を見たことがありますか?実際には、他の( "NULLバイト"例外なしの)ファイルと同様に妥当なCSVファイルのように見えますか?


この非常に詳細なヘルプをありがとうございました。ファイルには多くの\ x00文字が含まれています(質問の編集を参照)-奇妙です。なぜなら、テキストエディターでは完全に妥当なCSVファイルのように見えるからです。
AP257、2010年

1
@ AP257:'\xd0\xcf\x11\xe0\xa1\xb1\x1a\xe1OLE2複合ドキュメントファイル(Excel 97-2003 .XLSファイルなど)を示す「署名」です。「テキストエディタでは完全に妥当なCSVファイルのように見えます」とは信じられないほどわかります。別のフォルダー、別のマシン、または別の時点で、別のファイル、有効なCSVファイルを確認している必要があります。od出力はXLSファイルからのものではないことに注意してください。
John Machin、

8
@ AP257:この回答を受け入れなかった特別な理由はありますか?
John Machin、2011年

動作しますが、CSVをフィルタリングしてcsv.reader直接渡すことができるファイルのようなオブジェクトを使用して、オンザフライで実行できます。
gerrit

1
すべきではfo.write(data.replace('\x00', ''))ないfo.write(data.replace(b'\x00', b''))?ここにPython 3.6 ...
Boern

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

これでうまくいきます。


私の場合は解決されましたが、ヌルは '\ 0'値でした。ありがとう。
Joab Mendes

19

UTF-16として読み取ることも私の問題でした。

これが動作するようになった私のコードです:

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

場所はcsvファイルのディレクトリです。


13

私もこの問題にぶつかった。Python csvモジュールを使用して、MS Excelで作成されたXLSファイルを読み取ろうとしたところ、NULL byte発生したエラーが発生しました。MS Excelスプレッドシートファイルからデータを読み取り、フォーマットするためのxlrd Pythonモジュールを探しました。このxlrdモジュールを使用すると、ファイルを適切に読み取ることができるだけでなく、以前は不可能だった方法でファイルのさまざまな部分にアクセスすることもできます。

それはあなたを助けるかもしれないと思った。


7
そのモジュールを指摘してくれてありがとう。興味深いことに、私はそれをダウンロードしに行ったところ、著者がこの質問のトップコメントでもある@John_Machinにほかならないことに気づきました。
エヴァン

11

ソースファイルのエンコーディングをUTF-16からUTF-8に変換すると、問題が解決します。

Pythonでファイルをutf-8に変換する方法は?

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)

7

null値が存在しないふりをしたい場合は、ジェネレーターをインライン化してnull値を除外できます。もちろん、これはnullバイトが実際にはエンコードの一部ではなく、実際には何らかの誤ったアーティファクトまたはバグであると想定しています。

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

2

なぜあなたはこれをやっている?

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

ドキュメントはあなたがこれをしなければならないことをかなり明確です:

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

読み取るには、モードを「rb」にする必要があります。

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

csvfileがファイルオブジェクトの場合、違いがあるプラットフォームでは 'b'フラグで開く必要があります。


@ AP257:「助けにならない」?どういう意味?特定のエラーメッセージはありますか?
S.Lott、2015年

1
@ S.Lott:以前と同じ答えが得られることを意味します。実際のところ、彼はカメレオンまたはシェイプシフターファイルを処理しています。それをダンプしodたり、テキストエディターで見たりすると、完全に通常のCSVファイルのように見えます。ただし、Python repr()で最初の数バイトをダンプすると、Excel .XLSファイルのようになります(CSV拡張子を持つように名前が変更されています)。
John Machin

@ジョンマチン:「CSV拡張子を持つ名前に変更されていますExcelの.xlsファイルが(」それがすべてでは処理できないことは理にかなっています。
S.Lott

1
@ S.Lott:そのコンテンツでは、csvモジュールがそれを処理できないのは理にかなっています。ただし、xlrdモジュールはそれを処理できます。入力が名前の付いたファイルである場合、どちらのモジュールも入力ファイルの名前から何も推測しません。
John Machin、2010年

1
@John Machin:「どちらのモジュールも入力ファイルの名前から何も推測しません」。そうだね。私のアプリケーションフレームワークはその事実に依存しています。人々は間違いを犯す(「嘘」)ので、ファイル名が何かを意味するとは信じていません。したがって、1回のクリックまで、一連の選択肢を確認する必要があります。
S.Lott、2010年

2

どうやらそれはXLSファイルであり、http: //www.garykessler.net/library/file_sigs.html 確認としてCSVファイルではありません


必ずしもそうとは限りませんが、そうです、これが原因である可能性があります。Excelで保存されたCSVファイルをXLSXファイルから解析しようとしたときに、このエラーが発生しました。
Cerin

このマジックナンバーが原因で、XLSXのマジックナンバーが異なります
Xavier Combelle 2015年

2

csvリーダーの代わりに、ファイルの読み取りと文字列の分割関数を使用します。

lines = open(input_file,'rb') 

for line_all in lines:

    line=line_all.replace('\x00', '').split(";")

1

同じエラーが発生しました。ファイルをUTF-8で保存すると、正常に動作しました。


1
同じエラーメッセージが表示された可能性がありますが、原因は異なっていたでしょう-おそらく、もともとそれをUTF-16(メモ帳が「Unicode」と呼んでいるもの)として保存した可能性があります。
John Machin、2011年

1

これは、OpenOffice CalcでCSVファイルを作成したときに起こりました。後でCalcで編集しても、テキストエディタでCSVファイルを作成したときには起こりませんでした。

テキストエディターで、Calcで作成したファイルから新しいエディターで作成したファイルにデータをコピーアンドペーストして問題を解決しました。


1

空のヘッダーにNULLバイトを挿入するWebサービスから生成されたCSVを開く同じ問題がありました。私はファイルをきれいにするために次のことをしました:

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

免責事項:これにより元のデータが上書きされることに注意してください。それのバックアップコピーがあることを確認してください。警告されました!


0

それらすべての「rU」ファイルモード嫌い:「rb」ファイルモードでMac上のWindowsマシンからCSVファイルを開こうとしたところ、csvモジュールから次のエラーが発生しました。

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

「rU」モードでファイルを開くと問題なく動作します。私はユニバーサルニューラインモードが大好きです。面倒な作業が省けます。


0

これは、スクレイピーを使用し、応答ミドルウェアをcsvreaderに渡す前に適切なミドルウェアを解凍せずに、zipされたcsvfileをフェッチするときに発生しました。したがって、ファイルは実際にはcsvファイルではなく、line contains NULL byteそれに応じてエラーをスローしました。


0

gzip.openを使用してみましたか?

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

圧縮されていても「csv.gz」ではなく「.csv」の拡張子が付いたファイルを開こうとしました。このエラーは、gzip.openを使用するまで表示され続けました


-1

1つのケースは、CSVファイルに空の行が含まれている場合、このエラーが表示される場合があります。書き込みまたは読み取りに進む前に、行のチェックが必要です。

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

このチェックをコードに追加して問題を解決しました。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.