使用excel导出的csv发生奇怪的csv.reader行为

时间:2015-01-26 19:12:08

标签: python excel csv encoding

我一直在尝试解析从Excel保存的csvs,默认情况下发现它们似乎是ISO-8859-2(至少,chardet认为80%的确定性),我可以让它们解析。但是在解析版本中,单行被读出为两个单独的行。

我已根据csv模块的文档设置我的处理链,以使用正确的编码打开源文件,并通过UTF8Recoder运行它以在读入时将其转换为UTF-8。

概括看起来像这样:

f = codecs.open("/path/to/csv", "r+b", encoding="ISO-8859-2")
reader = csv.reader(UTF8Recoder(f))
for row in reader: print row

对于包含单行的CSV,这将输出2行!

通过命令行上的vim查看,csv的内容为:

UCL,,,10.1016/j.neuropsychologia.xxxx,Elsevier,Neuropsychologia,DAT genotype modulates striatal processing and long-term mem<85>,091593/Z/10/Z,,,CC BY,

,输出

['UCL', '', '', '10.1016/j.neuropsychologia.xxxx', 'Elsevier', 'Neuropsychologia', 'DAT genotype modulates striatal processing and long-term mem\xc2\x85']
['', '091593/Z/10/Z', '', '', 'CC BY', '']

如果我放弃所有字符编码处理,并让图书馆做任何他们想做的事情,我不会得到这种行为。相反,它似乎工作:

f = codecs.open("/path/to/csv", "r+b")
reader = csv.reader(f)
for row in reader: print row

输出是:

['UCL', '', '', '10.1016/j.neuropsychologia.xxxx', 'Elsevier', 'Neuropsychologia', 'DAT genotype modulates striatal processing and long-term mem\x85', '091593/Z/10/Z', '', '', 'CC BY', '']

任何人都可以了解正在发生的事情吗? (我注意到\ xc2 \ x85已成为\ x85,如果这表明什么的话)

我宁愿将输入数据显式编码为UTF-8,这样我就不必担心我的应用程序中的任何其他地方,实际上我怀疑在导入期间不指定编码会导致其他问题,如果我对字符编码的经验是可以接受的!

任何提示都非常感激。

编辑:这似乎是相关的:http://www.voidspace.org.uk/python/weblog/arch_d7_2010_01_02.shtml

\ x85是一个控制代码,当latin-1转换为unicode时,这意味着“换行符”。

如果是这样,我想我需要一种方法来阻止这种情况发生。

EDIT2:这也是相关的:http://mg.pov.lt/blog/latin1-or-cp1252

看来cp1252看起来很像iso-8859-1(又名latin-1)。我最初考虑过这个,但是把它称为“windows-1252”。使用输入编码“cp1252”的初步调查看起来很有希望。

1 个答案:

答案 0 :(得分:0)

经过大量挖掘后,我找到了解决方案。我上面的EDIT2中的最后一个链接让我意识到我不知道存在的字符编码:“cp1252”。令人遗憾的是,cp1252中的“正常”字符等同于iso-8859-2“换行符”字符。因此,如果您明确地将cp1252编码的文件读取为iso-8859-2,那么您将获得不期望它们的新行,这就是破坏csv解析器的原因。

请注意,尽管明显相似,但windows-1252和cp1252并不相同,至少在解析字节时可能会导致一个异常而不是另一个异常 - 我没有关于确切的任何细节这些编码之间的差异。

另请注意,我最初根据数据运行chardet对iso-8859-2进行了字符编码的确定,这使得编码概率为80% - 这还不够高。)

为了在我的软件中对此进行长期解决,我列出了我期望从csvs中获得的常见编码格式,并按可能性顺序尝试它们,直到我得到一个解析,并输出形状的csv我希望(在这种情况下,完全是矩形) - 两个部分都很重要,因为文件可能使用错误的编码进行解析,但可能不会产生结构上合理的csv。