6

我正在开发一系列解析器,从我的单元测试中得到一堆回溯,例如:

  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() 打开的,没有额外的争论。我可以将额外的参数传递给 open() 或使用编解码器模块中的某些东西以不同的方式打开这些参数吗?

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

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

4

3 回答 3

15

位置 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 在其中做了什么。

于 2010-07-19T22:06:24.593 回答
4

您可以放松错误处理。

例如:

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

或者:

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

请参阅文档

编辑:

但是您确定问题出在读取文件上吗?是否会在将某些内容写入控制台时发生异常?检查http://wiki.python.org/moin/PrintFails

于 2010-07-19T20:36:28.273 回答
2

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

正如回溯和错误消息所示有问题的文件未编码为cp1252.

如果它被编码为latin1,则"\x81"它抱怨的是一个 C1 控制字符,它甚至没有名称(在 Unicode 中)。考虑latin1极不可能是有效的。

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

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

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

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

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

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

于 2010-07-19T22:40:29.723 回答