我一直在尝试编写一个简单的控制台应用程序或PowerShell脚本来提取大量PDF文档中的文本。有几个库和CLI工具可以完成此任务,但事实证明没有一个能够可靠地识别文档结构。特别是我担心的是文本列的识别。即使是非常昂贵的PDFLib TET工具也经常混淆两个相邻文本列的内容。
经常注意到PDF格式没有任何列的概念,甚至没有单词。类似问题的几个答案在SO上提到了这一点。问题如此之大,以至于它甚至需要学术研究。这篇期刊文章指出:
所有PDF文件中的数据对象都以视觉导向的方式表示,作为一系列运算符,这些运算符通常不传达关于更高级别文本单位(例如令牌、行或列)的信息——有关这些单位之间边界的信息仅通过空格隐含地提供。
因此,我尝试过的所有提取工具(iTextSharp、PDFLib TET和Python PDFMiner)都未能识别文本列边界。其中,PDFLib TET表现最佳。
然而,SumatraPDF这个非常轻巧且开源的PDF阅读器和许多类似的应用程序可以完美地识别列和文本区域。如果我在其中一个应用程序中打开一个文档,在页面上选择所有文本(甚至使用CTRL+A选择整个文档),将其复制并粘贴到文本文件中,文本几乎完美地按正确顺序呈现。它偶尔会将页脚和页眉文本混合到其中一个列中。
经常注意到PDF格式没有任何列的概念,甚至没有单词。类似问题的几个答案在SO上提到了这一点。问题如此之大,以至于它甚至需要学术研究。这篇期刊文章指出:
所有PDF文件中的数据对象都以视觉导向的方式表示,作为一系列运算符,这些运算符通常不传达关于更高级别文本单位(例如令牌、行或列)的信息——有关这些单位之间边界的信息仅通过空格隐含地提供。
因此,我尝试过的所有提取工具(iTextSharp、PDFLib TET和Python PDFMiner)都未能识别文本列边界。其中,PDFLib TET表现最佳。
然而,SumatraPDF这个非常轻巧且开源的PDF阅读器和许多类似的应用程序可以完美地识别列和文本区域。如果我在其中一个应用程序中打开一个文档,在页面上选择所有文本(甚至使用CTRL+A选择整个文档),将其复制并粘贴到文本文件中,文本几乎完美地按正确顺序呈现。它偶尔会将页脚和页眉文本混合到其中一个列中。
所以我的问题是,这些应用程序如何做到看起来如此困难(即使对于PDFLib这样的昂贵工具)?
编辑于2014年3月31日:就我所知,PDFBox在文本提取方面比iTextSharp好得多(尽管进行了定制策略实现),而PDFLib TET比PDFBox略好,但价格相当昂贵。Python PDFMiner无望。最好的结果来自谷歌。人们可以将PDF上传到Google Drive(每次2GB),然后将其下载为文本。这就是我正在做的事情。我编写了一个小工具,将我的PDF拆分为10页文件(Google只会转换前10页),然后在下载后将它们拼合在一起。
2014年4月7日更新:取消上次的建议。最好的提取方法是使用MS Word。这可以在Acrobat Pro中自动化(工具>操作向导>创建新操作)。使用.NET OpenXml库可以自动将Word转换为文本。这里有一个类可以非常干净地执行提取(从docx到txt)。我的初步测试发现,与文档结构相关的MS Word转换要准确得多,但一旦转换为纯文本,则此问题并不那么重要。