簡體   English   中英

在Python中從gzip格式的CSV刪除BOM

[英]Removing BOM from gzip'ed CSV in Python

我正在使用以下代碼解壓縮並保存CSV文件:

with gzip.open(filename_gz) as f:
    file = open(filename, "w");
    output = csv.writer(file, delimiter = ',')
    output.writerows(csv.reader(f, dialect='excel', delimiter = ';'))

一切似乎都有效,除了文件中的第一個字符是意外的。 谷歌搜索似乎表明它是由於文件中的BOM。

我已經讀過,將內容編碼為utf-8-sig應該可以解決此問題。 但是,添加:

.read().encoding('utf-8-sig')

到csv.reader中的f失敗:

File "ckan_gz_datastore.py", line 16, in <module>
    output.writerows(csv.reader(f.read().encode('utf-8-sig'), dialect='excel', delimiter = ';'))
File "/usr/lib/python2.7/encodings/utf_8_sig.py", line 15, in encode
    return (codecs.BOM_UTF8 + codecs.utf_8_encode(input, errors)[0], len(input))
UnicodeDecodeError: 'ascii' codec can't decode byte 0xef in position 0: ordinal not in range(128)

如何刪除BOM表並將其內容保存在正確的utf-8中?

首先,您需要解碼文件內容,而不是編碼它們。

其次, csv模塊不喜歡Python 2.7中的unicode字符串,所以解碼了你需要轉換回utf-8的數據。

最后, csv.reader在文件的行上傳遞迭代,而不是在其中包含換行符的大字符串。

所以:

csv.reader(f.read().decode('utf-8-sig').encode('utf-8').splitlines())

但是,您可能會認為只是手動刪除BOM更簡單/更有效:

def remove_bom(line):
    return line[3:] if line.startswith(codecs.BOM_UTF8) else line

csv.reader((remove_bom(line) for line in f), dialect = 'excel', delimiter = ';')

這是微妙的不同,因為它從任何以1開頭的行中移除BOM,而不是僅從第一行開始。 如果您不需要保留其他BOM,那么可以使用以下方法進行修復:

def remove_bom_from_first(iterable):
    f = iter(iterable)
    firstline = next(f, None)
    if firstline is not None:
        yield remove_bom(firstline)
        for line in f:
            yield f

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM