PDF文本提取难在哪?

原文地址:What’s so hard about PDF text extraction?

译者:f00bar/LanceZhu

译文仅供个人学习,不用于任何形式商业目的,转载请注明文章来源、翻译作者及译文链接,版权归原文作者所有。


译者按:直观感觉,PDF 中复制文本应当如从 Microsoft Word 中复制文本一样容易。然而事实是,并不能从 PDF 中直接选择复制文本。本文则指出了导致 PDF 文本提取的几个难点,并予以例证,解决了存在的疑惑。还简要给出了 PDF 文本提取的方案。


大家通常认为从 PDF 文件中提取文本不会太难。毕竟文字就在我们眼前而且我们也一直非常成功地消费着 PDF 格式的内容。那么,为什么自动提取文本数据这么难呢?

处理人名的难点在于存在大量的边界情况和错误假设,处理 PDF 文件的难点则在于 PDF 格式的极度灵活性。

PDF 格式的主要问题在于其并不是作为输入数据格式来设计的,而是被设计成一种能够精细地调整以适应目标外观的输出格式。

PDF格式的核心点为用来描述如何绘制页面的一系列指令。特别是文本数据不是以段落甚至以单字来存储的,而是作为放置在页面固定位置的字符来存储。这样做的结果就是,当把文本文件转为 PDF 后,大部分文本语义丢失了,内在的文本结构在页面中也异常混乱。

作为构建 FilingDB 的一部分,我们提取了上万份 PDF 文件中的文本数据。在这个过程中,我们做的关于 PDF 文件是如何被组织的假设全被推翻了。我们要处理来自各种源,各种样式、排版的 PDF 文件,这更加增加了文本提取的难度。

以下列出了一些使文本提取工作操作困难甚至不可能的 PDF 处理方法。

PDF 读保护

你可能遇到过 PDF 禁止复制其内容的情况。比如说,这里是当从 SumatraPDF 中尝试复制一份禁止复制的文件时的结果。

有趣的是,文本是可见的但是 PDF 阅读器仍拒绝将高亮部分内容复制到剪切板上。

这是通过设置 访问控制 标志位实现的,其中的一个标志位控制着是否允许复制内容。但是我们要知道这种限制并不是由 PDF 文件内部强制实现,PDF 的实际内容并没有收到影响而是取决于 PDF 阅读器遵循标志位来限制文本复制。

更不必说,这种限制根本不会对 PDF 内容的提取起到保护作用,因为任何稍复杂的 PDF 处理库都会允许使用者选择遵循或忽略标志位。

页面外字符

相较于肉眼可见的文本,PDF 文件中通常包含更多文本内容。以2010年 Nestle 年度报告来说。

相较于肉眼所见的部分,这个页面中包含更多的文字。具体就是,以下内容可以在页面里找到。

“KitKat celebrated its 75th anniversary in 2010 but remains young and in touch with trends, having over 2.5 million Facebook fans. It is sold in over 70 countries and enjoys good growth in the developed world and emerging markets, such as the Middle East, India and Russia. Japan is its second biggest market.”

这类文本通常被插在页面边界外,因此不会被大多数 PDF 阅读器显示出来,但是它们确实存在于 PDF 文件中,可以通过程序提取出来。

这种情况时常发生于排版过程中的文本移除或替代的最后决策。

页面中的小或不可见字符

PDF 偶尔会在页面中引入非常小的或者不可见字符。例如,下面是2010年 Nestle年度报告中的一页。

这个页面在白色背景中包含了以下白色小字:

“Wyeth Nutrition logo Identity Guidance to markets

​ Vevey Octobre 2012 RCC/CI&D”

有时这么做是出于可访问性的考量,类似于 HTMLalt 标签的作用。

过多空格

有时 PDF 会在文字间插入额外的空格。这主要是为了调整字符间距。

例子:2013年 Hikma Pharma 年度报告中包含有以下内容。

复制文本得到:

“ch a i r m a n ‘ s s tat em en t”

重构出原始文本通常来说是个困难的问题。我们采取的最有效的方法是利用 OCR 识别。

没有足够的空格

有时 PDF 中不包含空格或者是使用其他字符来替换掉空格。

例证1: 2017年 SEB 年度报告

提取文本:

“Tenyearsafterthefinancialcrisisstarted”

例证2:2013你那 Eurobank 年度报告

提取文本:

“On_April_7,_2013,_the_competent_authorities”

再次强调,我们在此类 PDF 中提取文本的最有效方法就是使用 OCR。

内嵌字体

即使是退一步说,PDF 字体处理也是复杂的。为了理解 PDF 是如何存储文本数据的,我们首先要知道字形,字形名和字体。

  • 字形:一组用来描述如何绘制符号或字符的指令。

  • 字形名:与字形相关的名称。

    例如商标之于

  • 字体:一系列字形和与字形匹配的字形名。

    例如,大多数字体都会有一个为大多数人识别成 a 的字形,只是不同字体有不同的绘制方式。

在 PDF 中,字符被存作数字,称为”码点“。当在屏幕上绘制时,渲染器要经过以下过程:

码点 -> 字形名 -> 字形

比如说,一个 PDF 文档包含 码点 116,映射到字形名则为 t,再次映射到字形则为屏幕上的 t

当下,大多数 PDF 文件使用标准码点编码。码点编码是指用来为码点赋予具体含义一组规则。例如:

  • ASCII 和 Unicode 编码均使用码点来代表字符 t
  • Unicode 用笑脸 ☺ 代表 码点9786,在 ASCII 中则没有对应的符号。

然而,PDF 文件有时会使用自定义编码规则。这可能看起来有些奇怪,但是这样的话就可以使用码点1来代表字符t。这种编码规会将码点1映射到字形名c1,然后在映射到字形t

尽管对于人来说,最后的结果可能一致,但是机器则会感到疑惑。如果一个码点不遵循标注编码规则,那么就不可能通过编程得出码点 123分别代表什么。

为什么一个 PDF 文件会包含非标准字体和编码呢?

  • 加大文本提取难度。
  • 使用字体子集。大多数字体包含非常多的码点,PDF 文件则可能只使用其中的一部分。为了节省空间,PDF 创建者把无用字形全部移除,然后创造一个更紧凑的子集字体,而这种字体有极大可能性使用非标准编码。

对于此类问题的一个解决方案就是通过 OCR 识别建立字形到 unicode 的映射关系。这种方法可以使你将字体级别的编码转成 unicode 编码。例如:码点 1被映射到字形名c1,通过 OCR 识别,识别为字形t,在 unicode 编码中则为码点116

我们刚阐述的,1 -> 116。这种编码关系的映射在 PDF 标准中称作 ToUnicode 映射。PDF 文件可以提供它们自己的 ToUnicode 映射表,但是这是可选的而且大多数都不这么做。

文字和段落识别

从混乱的字符集中重构出段落甚至文字都是一个困难的任务。

PDF 文件仅提供了一组页面上的字符,文字和段落取决于消费者去识别。因为阅读是一个普遍的技巧,人类天生擅长做此类事情。

处理此类问题的通用方法是使用一个分组或聚类算法来比较字符大小、位置和对齐来决定其是否为文字或段落。

简单的实现方法复杂度很容易超过 O(n²) ,导致页面处理时间过长。

文本和段落顺序

决定文本和段落顺序的困难性有两层原因。

第一,有时根本没有正确的顺序。单列排版有很自然的阅读顺序,然而有着更独特排版的文件决定顺序则具有挑战性。举例来说,并不清晰以下的插入部分应当出现在其相邻文章的前中后位置。

第二,即使对人来说可以决定顺序,但是是决定段落顺序仍是一个非常困难的问题,甚至对 AI 来说仍是困难的。这可能听起来是一个极端的陈述,然而会有在只有理解文本内容时才能得出正确段落顺序的情形。

阅读以下两列结构的内容,描述如何做一个蔬菜沙拉。

在西方世界里,阅读顺序通常是从左到右,自上及下。所以我们可以在不看其中内容的情况下将可能结果减少到两种情况: A B C D 和 A C B D。

通过阅读其中内容,理解了文中所述,得知蔬菜应当先洗再切,我们便能得出 A C B D 才是正确顺序。通过算法来决定顺序则是困难的问题。

话虽如此,在大多数情况下奏效的方法却是依赖 PDF 文件中文本存储的顺序。这通常与文本在创建时被插入的顺序相关,在包含多个段落的大文本中,插入顺序往往反映了写作者的意向顺序。

内嵌图片

PDF 内容是扫描件的情况并不少见。在这种情况下,无法直接提取文本数据,我们只能通过 OCR 识别。

比如2011年 Yell 的年度报告只能获得一份扫描件。

为什么不总是通过 OCR 识别?

尽管 OCR 在以上一些问题中有帮助,但它仍有自己的一些缺点。

  1. 处理时间长

    通过 OCR 识别 PDF 文档的时间通常要比直接从 PDF 中提取文本要高一个数量级。

  2. 处理非标准字符和字形难

    OCR 识别算法难以处理新兴字符,比如说笑脸,星星、圆圈、方块(在点状列表中使用),上标和复杂的数学符号等等。

  3. 无文本顺序提示

    在插入顺序(大多数情况下是正确的阅读顺序)的提示下,为 PDF 中提取出的文本排序会更容易。然而从图片中提取出的文本没有这种提示。

测试

到目前为止,我们未提到的困难是如何确认所提取出文本是否是正确的或者是预期的。我们得到的最有用方法是通过大量测试集去校验基础标准(比如说文本长度,空格文字比率)、更复杂的标准(比如说英文文本与不能识别文字的比率,数字占比)和检查异常标记比如可疑或非预期字符。

所以,我们关于从 PDF 中提取文本的意见是什么呢?在进行 PDF 提取前确保没有更好的其它数据源。

如果你感兴趣的数据只有 PDF 格式,那么你务必要意识到 PDF 文本提取是一个具有欺骗性的看似简单的问题,100% 正确提取的方案有可能是无法实现的。