如何读取包含井号的CSV文件?

时间:2016-01-10 23:32:10

标签: python encoding

我的文件开头有一个NUL字节,我很难用“£”符号

data_initial = codecs.open(filename, "rU", "utf-16")
data = csv.DictReader((line.replace('\x00','') for line in data_initial), delimiter="\t")
    for row in data:
        print row

我收到错误:

  

UnicodeEncodeError:'ascii'编解码器无法对字符u'\ xa3'进行编码   位置169:序数不在范围内(128)

顺便说一句:如果我尝试打印这条线是否无关紧要。我只能打印'1',错误保持不变。我不知道为什么它说这是一个编码错误,当它可能是一个解码错误。

无论如何,我该如何处理这个问题?

2 个答案:

答案 0 :(得分:2)

问题几乎可以肯定,codecs.open(filename, "rU", "utf-16")正在以与csv不兼容的方式转换“£”符号:

  

此版本的csv模块不支持Unicode输入。此外,目前有一些关于ASCII NUL字符的问题。因此,所有输入应为UTF-8或可打印的ASCII以确保安全;请参阅示例部分中的示例。

只需将编码类型更改为“utf-8”(假设文件中没有不兼容的符号)就可以解决问题:codecs.open(filename, "rU", "utf-8")

答案 1 :(得分:1)

我假设你在这里使用Python 2.7。在Python 2.7下,CSV不支持python unicode字符串。您必须以原始二进制文件读取文件,然后在 csv返回后解码字符串。您正在阅读文件时无法对文件进行解码,并希望csv能够处理它;我的经验是它不会应付。

这在Python 3.x中非常不同,其中csv支持Unicode,并且必须在csv读取数据之前进行解码。或者它不会工作。

两种情况之间存在如此大的差异,这有点令人讨厌。

我的旧版但经过测试的代码适用于所有Python版本看起来像(怀疑你应该能够用你想要的任何东西替换" ascii")。是的,只是注意到一些断言在某种程度上毫无意义,但无论如何引用原始测试代码。

if sys.version_info < (3, 0):
    # Python2: csv module does not support unicode, we must use byte strings.   

    def _input_csv(csv_data):
        for line in csv_data:
            assert isinstance(line, bytes)
            yield line

    def _output_csv(csv_line):
        for i, column in enumerate(csv_line):
            csv_line[i] = column.decode("ascii", errors='ignore')
            assert isinstance(csv_line[i], unicode)  # NOQA

else:
    # Python3: csv module does support unicode, we must use strings everywhere, 
    # not byte strings

    def _input_csv(unicode_csv_data):
        for line in unicode_csv_data:
            assert isinstance(line, bytes)
            line = line.decode("ascii", errors='ignore')
            assert isinstance(line, str)
            yield line

    def _output_csv(csv_line):
        for column in csv_line:
            assert isinstance(column, str)

我在哪里读取(在这种情况下来自子进程):

reader = csv.reader(_input_csv(process.stdout), delimiter="|")
for row in reader:
    _output_csv(row)