【问题标题】:How to deal with <FE><FF> in what should be valid utf-8? What am I doing wrong?如何以有效的 utf-8 处理 <FE><FF>?我究竟做错了什么?
【发布时间】:2012-11-29 03:26:29
【问题描述】:

我正在使用带有选项“-enc utf-8 -htmlmeta -raw”的pdftotext 并将其传递给解析输出的python 脚本。 (即使您不熟悉 pdftotext,也请继续阅读,因为这可能不相关。)

对于我们正在处理的一些 pdf,pdftotext 正在输出如下所示的元数据:

<meta name="CreationDate" content="<FE><FF>">

在 python 中,我正在这样做(基本上):

attrib[name] = content.decode('utf-8')

其中content 是上述元数据中的&lt;FE&gt;&lt;FF&gt; 字符串。 Python 引发异常:

UnicodeDecodeError: 'utf8' codec can't decode byte 0xfe in position 0: unexpected code byte

在这一点上,我不确定问题是 PDF 本身,还是 pdftotext 的输出,还是 Python 解释 utf-8 的方式。

我用谷歌搜索过,没有找到任何结论。

基本上,我希望pdftotext -enc utf-8输出有效的 utf-8。我希望 Python 在解码时能够理解如何处理该 utf-8。我缺少其中的某些部分吗?

如果能帮助我理解为什么会发生这种情况并提供解决方案,我将不胜感激。

谢谢!

【问题讨论】:

  • 0xFE 0xFF 是 UTF-16 大端字节序标记。它表示文件的字符编码,这意味着 Python 将其视为 UTF-16 而不是 UTF-8。

标签: python unicode utf-8 pdftotext


【解决方案1】:

两件事:

首先,不要使用content.decode('utf-8'),而是使用:

content.decode('utf-8-sig')

这将自动删除 BOM(如果存在)。

其次,看起来pdftotext 正在输出 UTF-16 BOM,而不是 UTF-8 BOM。 UTF-8 BOM 是 '\xEF\xBB\xBF'。您需要弄清楚为什么要使用 UTF-16,或者将脚本更改为从 UTF-16 解码。

【讨论】:

  • 感谢您的快速响应。我已经尝试过 utf-8-sig,但无济于事。奇怪的是,我们正在处理大约 100k PDF,其中似乎只有大约 500 个存在这个问题。而且每次都是完全相同的字符“0xfe”。解码为 utf-8 没有其他问题,这是预期的输出。使用 utf-16 会有什么危害吗?或者是在调用 content.decode() 之前简单地删除这个字符序列的更简洁的方法?谢谢!
  • @jeffp:嗯,如果不一致,可能字节来自 PDF 本身——在这种情况下,您可以切换到 UTF-16 来掩盖问题或手动检查并剥离自己去掉多余的 BOM。如果引发异常,也许try utf-8-sig 并回退到 UTF-16?
  • 我尝试了一个简单的测试,我尝试了 utf-16,但我得到了一个不同的错误:“UnicodeDecodeError: 'utf16' codec can't decode byte 0x0a in position 7804: truncated data” 谢谢至少验证它是不一致的。我想我会剥离这些字节。
  • 我也可以这样做:content.decode('utf-8','ignore') 不过这似乎不是一个干净的方法。
  • @jeffp:是的,解析真实世界数据的乐趣 :-) 对于这个问题并没有真正的“最佳答案”,因为某些数据似乎会以一种方式损坏或其他。我想最好的选择是在你的实际数据集上产生最好的结果。
猜你喜欢
  • 2013-08-06
  • 1970-01-01
  • 2016-07-18
  • 2019-12-23
  • 2014-06-15
  • 1970-01-01
  • 2015-08-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多