parsing - 解析 PDF 文件并输出单个字符位置
问题描述
我试图通过识别每个字符和每个单词的内容和位置来从(数字)PDF 中提取文本信息。对于单词,pdftotext --bbox
来自 xpdf / poppler 的效果很好,但我找不到提取字符位置的简单方法。
我试过的
我目前拥有的解决方案是将pdf转换为svg(通过pdf2svg
),然后解析生成的svg以提取单个字符(=字形)位置。第三步,比较结果框,将每个字符分配给一个单词,并希望数字匹配。
问题
虽然上述方法适用于大多数“基本”字体,但这种方法在两种(主要)情况下会失败:
- 在脚本字体(或一些极端的斜体字体)中,边界框比它们的内容大得多;结果,单词有很大的重叠,很可能一个字符完全包含在两个单词中。在这种情况下,映射失败,因为一旦我转换为 svg,我就没有关于哪个字符包含在哪个字形中的信息。
- 在许多字体中,可以连接多个字符,从而产生单个字形。在这种情况下,字符框的计数与单词中的字符数不匹配,并且将每个字母匹配到一个框又是有问题的。
第二点(对我来说是主要的)通过识别常见的连字和(如果计数不匹配)将相应的边界框分成多个部分来解决部分问题;但这并不总是有效,因为例如“ffi”有时会连接到单个字形,有时会连接到两个字形“ff”+“i”,有时会连接到两个字形“f”+“fi”,具体取决于字体。
我希望什么
据我了解,pdf 实际上包含字形信息,而不是文字。如果是这样,所有从 pdf 中提取文本的程序(如pdftotext
)必须首先提取并定位各种字符,然后将它们分组为单词/行;所以我有点惊讶我找不到为每个字符输出位置的选项。转换为 svg 本质上给了我这一点,但在转换中,所有关于内容的信息(即,如果有连字,则将字形到字符或字形到字符的映射)丢失,因为不再有字体了。并且通过再次查看字体来重做将每个字形与字符匹配的工作感觉就像重写 pdf 解析器......
因此,我将非常感谢有关如何解决此问题的任何想法。这里的最佳答案表明这可能对 TET 是可行的,但它是一种付费选择,并且更换我的整个基础设施来处理一个限制情况似乎是一个很大的矫枉过正......
解决方案
PDF 文件不一定明确指定每个字符的位置。通常,它将文本分成一系列字符(我认为都使用相同的字体,最多一行),然后为每次运行指定边界框的位置,该边界框应包含这些字符的字形。所以每个字形的确切位置将取决于用于渲染它的字体的度量(主要是字形宽度)。
Python 包pdfminer
有一个脚本pdf2txt.py
。尝试使用-t xml
. 文档只是说XML format. Provides the most information.
但是我的笔记表明它将应用字体度量并<text>
为每个字形提供一个元素,包括字体和边界框信息。
各个地方都有不同的版本(例如 PyPI 和 github)。如果您需要 Python 3 支持,请查找pdfminer.six
.
推荐阅读
- canvas - 为什么 webgl 画布上下文比 2d 画布使用更多的内存?
- r - 从 R 中的某个列开始将后续列向上移动一个额外的位置(滞后)
- linux - 如何在 Oracle Linux 7 上安装离线 RabbitMQ
- python - 正则表达式匹配多次出现的模式并忽略其间的内容
- reactjs - 如何使用 react-quill 添加从右到左的支持
- amp-html - 不能在 amp-mustache 中使用 amp-img?
- python - 如何检查 python InMemoryUploadedFile 文件的文件类型?
- python - Kivy 拒绝在 Windows 10 上安装 python 3.8.5
- java - 在 DOS 中运行 java 命令时如何在复杂的 Java 应用程序中查找丢失的类
- php - 如何在 DB Laravel 中将 3 个图像插入到 3 个字段