从乱码的PDF中提取文本

11

我有一份包含宝贵文本信息的PDF文件。

问题是我无法提取文字,得到的只是一堆乱码符号。如果我将文本从PDF阅读器中复制并粘贴到文本文件中,情况也是一样的。即使在Acrobat Reader中使用“文件 -> 另存为文本”也失败了。

我已经使用了所有能够找到的工具,结果都是相同的。我认为这可能与字体嵌入有关,但我不知道确切的原因。

我的问题:

  • 是什么导致了这种奇怪的文本乱码
  • 如何从PDF中提取文本内容(通过程序、工具、直接操作比特等)?
  • 如何修复PDF以避免复制时出现乱码

1
我重新修改了这个问题,因为它完全适合在SO上提问。实际上,PDF文件是自动文本提取的常见文件格式,而且已经有完美的答案回答了如何通过编程检查和解决这个问题(我也可以添加一个代码片段的答案来进行OCR)。我投票支持重新打开这个问题,因为它可能对其他开发人员有用。 - gaborous
3个回答

27
一些PDF文件缺乏特殊信息,这对于从中提取文本至关重要。即使使用Adobe工具也是如此。基本上,这样的文件不包含字形到字符映射信息。
这样的文件将被正确地显示和打印(因为字符的形状已经被定义),但无法正确复制/提取其中的文本(因为没有有关所使用字形/形状的含义的信息)。
例如,当使用“最小文件大小”预设时,Distiller会生成这样的文件。
除了OCR之外,恐怕没有其他方法可以从这样的文件中检索文本。我们最近发布了一个指南,介绍如何在.NET中进行OCR PDF
另外,我们还有一个示例代码,展示如何对未映射的字符执行OCR,然后用正确的Unicode值替换它们

补充原回答

原回答提到了使用的字形/形状的含义信息。这些信息应该包含在一个名为/ToUnicode表的PDF结构中。对于每个嵌入为子集并使用非标准(Custom)编码的字体,都需要这样的表。

为了快速评估提取文本内容的可能性,您可以使用pdffonts命令行实用程序。这会以表格形式打印有关PDF使用的每个字体的一系列项目。列标题为uni的存在表示存在/ToUnicode表。

以下是一些示例输出:

$ kp@mbp:git.PDF101.angea> pdffonts handcoded/textextract/textextract-good.pdf

    name                     type        encoding   emb sub uni object ID
    ------------------------ ----------- ---------- --- --- --- ---------
    BAAAAA+Helvetica         TrueType    WinAnsi    yes yes yes     12  0
    CAAAAA+Helvetica-Bold    TrueType    WinAnsi    yes yes yes     13  0


$ kp@mbp:git.PDF101.angea> pdffonts handcoded/textextract/textextract-bad1.pdf

    name                     type        encoding   emb sub uni object ID
    ------------------------ ----------- ---------- --- --- --- ---------
    BAAAAA+Helvetica         TrueType    WinAnsi    yes yes no      12  0
    CAAAAA+Helvetica-Bold    TrueType    WinAnsi    yes yes no      13  0


$ kp@mbp:git.PDF101.angea> pdffonts handcoded/textextract/textextract-bad2.pdf

    name                     type        encoding   emb sub uni object ID
    ------------------------ ----------- ---------- --- --- --- ---------
    BAAAAA+Helvetica         TrueType    WinAnsi    yes yes yes     12  0
    CAAAAA+Helvetica-Bold    TrueType    WinAnsi    yes yes no      13  0
< p > good.pdf 可以正确地提取两种字体的文本内容,因为这两种字体都有相应的 /ToUnicode 表。

对于 bad1.pdfbad2.pdf,只有一种字体具有 /ToUnicode 表,因此只能成功提取其中一种字体的文本内容,而另一种字体则失败。

我(Kurt Pfeifle)最近创建了一系列手工编码的 PDF 文件,以展示现有 PDF 源代码中存在的、错误的、被操纵的或缺失的 /ToUnicode 表的影响。这些 PDF 文件有广泛的注释,并适合使用文本编辑器进行探索。上面的 pdffonts 输出示例是使用这些手工编码文件创建的。(还有一些显示不同结果的 PDF,可能会引起感兴趣的读者的探索...)


3
基本上,这些文件不包含字形到字符映射信息,并且同时使用非标准(非ASCII)编码。在缺少正确的字形到字符映射信息的情况下,许多文本提取器假设某种标准编码并尝试进行提取。每当这个假设失败时,就会产生垃圾结果。 - mkl
1
我已经为您的答案点了赞,并补充了一些信息。希望您能接受 :-) - Kurt Pfeifle
4
我也投票赞成重新开放原帖(由于某些模糊的原因而被关闭)。 - Kurt Pfeifle
@KurtPfeifle 当然,谢谢你的补充。 - Bobrovsky
在这种情况下,您将如何提取内容或提取字体,然后将其应用于没有字体的提取内容? - Chetan Bhasin

12

我向很多人寻求帮助,OCR是唯一解决这个问题的方案。


4
如果你使用Microsoft Office,OneNote有一个非常不错的OCR功能,对于一份展示了上述问题的PDF文档,我使用它时获得了100%的准确率。 - David Airapetyan
1
我喜欢那个解决方案的疯狂程度.. :))))) - nicolas
什么是OCR?能否请您解释一下?我也遇到了同样的问题。 - Prince Sodhi
@Sodhisaab 光学字符识别。我使用了 https://github.com/tesseract-ocr/tesseract - SNAG

3

我曾经遇到同样的问题。将文件上传至Google Drive,用Google Docs打开,并从中复制文本,这对我有用。


4
更简单的解决方法是:将PDF文件拖到Chrome浏览器窗口中。你可以复制出文本——至少我可以这样做。 - gsziszi
对我有用。这个答案似乎比OCR答案更实用(除非构建某种自动化)。 (gsziszi的Chrome方法对我不起作用)。 - Steph Thirion
@gsziszi,您能否把您的评论变成答案?这个方法很有效,显然比使用OCR更实用。谢谢! - keyboardSmasher
不按照你说的方式对我起作用。我尝试了在Chrome窗口中打开文件以及将其上传到Google Drive并从那里打开两种方法。 - Waqas Shakeel
很遗憾,这不是原问题的同一个问题。真正的问题在这里描述:https://forums.adobe.com/thread/915012 - Edhowler
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接