Python 3扼流CP-1252 / ANSI读取

时间:2010-07-19 20:33:20

标签: python unicode latin1 cp1252 python-3.x

我正在研究一系列解析器,我从单元测试中得到一堆追溯,如:

  File "c:\Python31\lib\encodings\cp1252.py", line 23, in decode
    return codecs.charmap_decode(input,self.errors,decoding_table)[0]
UnicodeDecodeError: 'charmap' codec can't decode byte 0x81 in position 112: character maps to <undefined>

使用open()打开文件,没有额外的arguemnts。我可以将额外的参数传递给open()或者在编解码器模块中使用某些东西以不同的方式打开它们吗?

这提供了用Python 2编写并使用2to3工具转换为3的代码。

更新:事实证明这是将zipfile输入解析器的结果。单元测试实际上预计会发生这种情况。解析器应该将其识别为无法解析的内容。所以,我需要改变我的异常处理。现在正在这样做。

3 个答案:

答案 0 :(得分:14)

位置0x81在Windows-1252(又名cp1252)中未分配。它被分配给Latin-1(又名ISO 8859-1)中的U + 0081 HIGH OCTET PRESET(HOP)控制字符。我可以像这样在Python 3.1中重现你的错误:

>>> b'\x81'.decode('cp1252')
Traceback (most recent call last):
  ...
UnicodeDecodeError: 'charmap' codec can't decode byte 0x81 in position 0: character maps to <undefined>

或使用实际文件:

>>> open('test.txt', 'wb').write(b'\x81\n')
2
>>> open('test.txt').read()
Traceback (most recent call last):
  ...
UnicodeDecodeError: 'utf8' codec can't decode byte 0x81 in position 0: unexpected code byte

现在将此文件视为Latin-1,您传递encoding参数,如codeape建议:

>>> open('test.txt', encoding='latin-1').read()
'\x81\n'

请注意Windows-1257和Latin-1编码之间存在差异,例如: Latin-1没有“智能引号”。如果您正在处理的文件是文本文件,请问问自己\ x81正在做什么。

答案 1 :(得分:3)

您可以放松错误处理。

例如:

f = open(filename, encoding="...", errors="replace")

或者:

f = open(filename, encoding="...", errors="ignore")

请参阅the docs

修改

但是你确定问题在于阅读文件吗?将某些内容写入控制台时,是否会发生异常?查看http://wiki.python.org/moin/PrintFails

答案 2 :(得分:2)

所有文件都是“非Unicode”。 Unicode是必须编码的内部表示。您需要为每个文件确定使用了哪种编码,并在打开文件时指定必要的文件。

由于追溯和错误消息指示相关文件未在cp1252中编码。

如果它是在latin1中编码的,那么它所抱怨的"\x81"就是一个C1控制字符,它甚至没有名字(用Unicode表示)。 认为latin1极不可能有效。

你说“有些文件是用xml.dom.minidom解析的” - 解析成功还是失败?

有效的XML文件应在第一行声明其编码(默认为UTF-8),您不需要在代码中指定编码。向我们展示您用于执行xml.dom.minidom解析的代码。

“其他人直接读作迭代” - 请提供示例代码。

建议:尝试在浏览器中打开某些类型的文件。然后单击“查看”并单击“字符编码”(Firefox)或“编码”(Internet Explorer)。浏览器猜到了什么编码[通常可靠]?

其他可能的编码线索:文件中的文本使用了哪些语言?你从哪里得到文件?

注意:请用澄清信息编辑您的问题;不要在评论中回答。