如何从pdf中提取文本?

时间:2021-04-12 09:11:08

标签: parsing pdf pdf-parsing

我正在构建一个 pdf 解析器,用于提取文本并将其保存到 txt 文件中。
我是通过跟踪所有内容对象来实现的,然后使用字体编码对流进行解码。 我发现我有点挑战的是如何以正确的顺序放置文本,我不在乎它的实际外观,我想要的是序列的顺序,我不在乎字体大小,文本之间的空间...等

如果我只关心顺序,我该如何处理 Tm、Td、TD 和 T*?

另一个问题有时一个内容对象包含来自 2 个不同页面的流,我如何知道下一页的流何时开始?

1 个答案:

答案 0 :(得分:0)

因为你的问题很笼统,所以这个答案也很笼统。

<块引用>

如果我只关心顺序,我该如何处理 Tm、Td、TD 和 T*?

只有几个主要选项:

  • 除了显示运算符的文本外,您可以忽略所有内容,尤其是您可以忽略提到的运算符。相关数量的文档允许非常忠实地提取文本,因为这些文档中显示操作符的文本以自然阅读顺序出现。

    考虑到您问这个问题,似乎表明您遇到了不同构建的文档。

  • 如果相关文档被适当标记,您可以使用内容流中的 MCID 结合文档结构树来排序(和分类!)像以前一样提取。对于带标签的文档,这通常会产生合理的良好文本提取结果。

  • 否则,即使您“只”关心顺序,您也必须提取文本片段的确切位置以及这些片段本身,并最终对它们进行相应的排序。这意味着不仅要考虑您提到的操作,还要考虑 cm(更改当前变换矩阵)、q(保存当前图形状态)和 Q< /strong>(恢复当前图形状态)。

    此外,对于非常广泛的文档的解决方案,您还必须分析布局以识别属于图形而不是主要文本流的多个列和文本。

当然,这些主要选项可能会有一些变化,例如假设文本对象的顺序是正确的,并且只在其中进行排序;这些可能允许忽略某些运算符,例如在刚刚提到的示例中,可以忽略 cmqQ,因为它们不允许出现在文本对象中。

<块引用>

另一个问题有时一个内容对象包含来自 2 个不同页面的流,我如何知道下一页的流何时开始?

我不确定我是否理解正确。您的意思是从多个页面对象引用相同的内容流,这些页面对象仅显示内容的某些可能不同的部分?在这种情况下,您还必须提取文本片段的确切位置,并检查它们是否在相应页面的裁剪框内或外。

编辑

在评论中,您同时澄清并提供了示例数据。分析该数据会产生以下补充:

首先,并不是你在第 16 页的内容流中标记为蓝色的所有内容都可以在第 17 页而不是第 16 页上找到;例如,很早就(在“仔细查看对象 127”的第二行)您可以看到绘制页码 (16)Tj 的说明,该页码位于第 16 页,而不是第 17 页。

但实际上,很快就会有一大段文本对象开始,您只能在查看器中找到第 17 页的文本,而不是第 16 页。原因是这些文本对象绘制在可见页面区域之外和当前页面区域之外剪辑路径!

更详细:

第 16 页和第 17 页都有一个 [ 0.0 0.0 481.89 680.315 ]CropBox,即可见区域是画布的左下角为 (0, 0) 和 (481.89, 680.315)在右上角。

然后您会在第 16 页内容的早期部分中找到以下说明:

0 0 481.89 680.315 re
W n

这会将当前剪辑路径与左下角为 (0, 0) 且右上角为 (481.89, 680.315) 的矩形相交。

因此,在第 16 页的框外绘制的所有内容都是不可见的,原因有两个。

但是该内容中以蓝色标记的以下文本对象在具有负 x 坐标的位置绘制文本!例如在上面的剪辑路径更改说明之后:

BT
0 0 0 1 k
/GS1 gs
/C2_0 1 Tf
15 0 0 15 -441.875 556.9449 Tm
[<0003007000640059006E005F004300D0>-48<00030044004C>-47<000300CA006E>1<0066003D00ED>-48<000300BA007B0065005C003D>-48<000300700059006E005F005500D0>-47<0003007000650063009D004300D0>-48<0003007F006800FD00DA>-48<00030007000C000C000C0008>-45<0003006E006900CC>-47<000300EF007B00640052>-49<000300BA007B005F003D00ED>-48<000300EC007B004100ED>-48<00030101>-47<0003007B0065002200D0>]TJ
ET
EMC 
/Span <</MCID 243 >>BDC 
BT
/C2_0 1 Tf
15 0 0 15 -441.875 534.9449 Tm
[<0003008B0053007D003D>-289<0003007000650063009D0043006E003D>-289<000300D2007B00680062004300D0>-291<000300E50077>]TJ
ET
EMC 

那些文本矩阵设置指令的第五个条目 (Tm) 本质上是 x 坐标,接下来的文本绘制指令将从左到右绘制文本。 -441.875 的值显然在上面提到的框之外。

如果您查看以下第 17 页的内容流,您会发现绘制相同文本的类似说明:

BT
/C2_0 1 Tf
15 0 0 15 40.0148 556.9449 Tm
[<0003007000640059006E005F004300D0>-48<00030044004C>-47<000300CA006E>1<0066003D00ED>-48<000300BA007B0065005C003D>-48<000300700059006E005F005500D0>-47<0003007000650063009D004300D0>-48<0003007F006800FD00DA>-48<00030007000C000C000C0008>-45<0003006E006900CC>-47<000300EF007B00640052>-49<000300BA007B005F003D00ED>-48<000300EC007B004100ED>-48<00030101>-47<0003007B0065002200D0>]TJ
ET
EMC 
/Artifact <</O /Layout >>BDC 
BT
/C2_0 1 Tf
15 0 0 15 40.0148 534.9449 Tm
[<0003008B0053007D003D>-289<0003007000650063009D0043006E003D>-289<000300D2007B00680062004300D0>-291<000300E50077>]TJ
ET
EMC 

与第 16 页的说明相反,这里的 x 坐标是 40.0148,它显然位于第 17 页的 CropBox 内。


注意:上面我说那些文本矩阵设置指令的第五个条目 (Tm) 本质上是 x 坐标,下面的文本绘制指令将从从左到右绘制文本。这里的坐标是当前用户空间坐标

如果之前有cm指令,当前用户空间坐标不一定一定是默认用户空间坐标< /em> 其中定义了裁剪框。

但是,对于您的文档,在上述说明之前不使用 cm 说明。