archives
【转载】将 PDF 文件转换为文本
大多数PDF文件看起来都包含结构良好的文本。但现实情况是,PDF文件不包含任何类似于段落,句子甚至单词的内容。当涉及到文本时,PDF文件只知道字符及其位置。
这使得从PDF文件中提取有意义的文本片段变得困难。构成段落的字符与构成表格、页脚或图形描述的字符没有什么不同。与其他文档格式(如.txt文件或 Word 文档)不同,PDF 格式不包含文本流。
PDF 文档确实由一组对象组成,这些对象共同描述了一个或多个页面的外观,可能还附带了其他交互式元素和更高级别的应用程序数据。PDF 文件包含构成 PDF 文档的对象以及关联的结构信息,所有这些信息都表示为单个独立的字节序列。[注1]
布局分析算法
PDFMiner试图通过对字符定位使用启发式方法来重建其中一些结构。这适用于句子和段落,因为可以创建有意义的附近字符组。
布局分析由三个不同的阶段组成:它将字符分组为单词和行,然后将行分组到框中,最后按层次结构对文本框进行分组。以下各节将讨论这些阶段。布局分析的结果输出是 PDF 页面上布局对象的有序层次结构。
![]()
布局分析的输出是布局对象的层次结构。
布局分析的输出很大程度上取决于几个参数。所有这些参数都是 LAParams 类的一部分。
将字符分组为单词和行
从字符到文本的第一步是以有意义的方式对字符进行分组。每个字符的左下角和右上角(即边界框)都有一个 x 坐标和一个 y 坐标。Pdfminer.six 使用这些边界框来决定哪些字符属于一起。
水平和垂直接近的字符被分组到一行中。它们应该有多接近由char_margin(图中的M)和line_overlap(而不是图中)参数确定。两个字符的边界框之间的水平距离应小于char_margin边界框之间的垂直重叠应小于line_overlap。
→ ← 米 Q u i
c k
b r o w n
→ ← W char_margin和line_overlap的值相对于字符边界框的大小。char_margin相对于任一边界框的最大宽度,line_overlap相对于任一边界框的最小高度。
需要在字符之间插入空格,因为 PDF 格式没有空格字符的概念。如果字符的距离比word_margin(图中的 W)更远,则插入一个空格。word_margin相对于新字符的最大宽度或高度。较小的word_margin会创建较小的单词。请注意,word_margin应至少小于char_margin否则任何字符都不会被空格分隔。
此阶段的结果是行的列表。每行由一个字符列表组成。这些字符可以是源自 PDF 文件的原始 LTChar 字符,也可以是插入的 LTAnno 字符,表示单词之间的空格或每行末尾的换行符。
将行分组到框中
第二步是以有意义的方式对行进行分组。每行都有一个边界框,该边界框由它所包含的字符的边界框确定。与对字符进行分组一样,pdfminer.six 使用边界框对行进行分组。
水平重叠和垂直接近的线将被分组。线的垂直接近程度应由line_margin确定。此边距是相对于边界框的高度指定的。如果边界框的顶部(见图中的 L 1)和底部(见图中的 L 2)之间的间隙比绝对行距(即line_margin乘以边界框的高度)更近,则线条较近。
↓ Q u i c k b r o w n
↓ L1 f o x
↑ 二层 ↑ 此阶段的结果是文本框列表。每个框由一个行列表组成。
按层次结构对文本框进行分组
最后一步是以有意义的方式对文本框进行分组。此步骤重复合并彼此最接近的两个文本框。
边界框的接近度计算为两个文本框之间的区域(图中的蓝色区域)。换言之,它是围绕两条线的边界框的面积减去单条线的边界框的面积。
Q u i c k b r o w n
f o xj u m p s ...
使用旋转字符
上述算法假定所有字符具有相同的方向。但是,任何写作方向都可以在PDF中进行。为了适应这种情况,pdfminer.six允许使用detect_vertical参数检测垂直写入。这将应用所有分组步骤,就好像pdf旋转了90(或270)度一样
引用
[1] Adobe System Inc. (2007).Pdf 参考:Adobe 可移植文档格式,版本 1.7。