【问题标题】:How order text extracted from pdf?如何从pdf中提取文本?
【发布时间】:2023-04-02 18:53:01
【问题描述】:

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

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

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

【问题讨论】:

    标签: parsing pdf pdf-parsing


    【解决方案1】:

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

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

    只有几个主要选项:

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

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

    • 如果有问题的文档被适当标记,您可以使用内容流中的 MCID 与文档结构树组合来对您提取的文本片段进行排序(和分类!) .对于带标签的文档,这通常会产生合理的良好文本提取结果。

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

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

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

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

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

    编辑

    在 cmets 中,您同时澄清并提供了示例数据。分析该数据会产生以下添加:

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

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

    更详细的:

    第 16 页和第 17 页都有一个 CropBox[ 0.0 0.0 481.89 680.315 ],即可见区域是画布的左下角为 (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指令,当前用户空间坐标不一定一定是默认用户空间坐标 其中定义了裁剪框。

    但是,对于您的文档,在上面讨论的说明之前没有使用 cm 说明。

    【讨论】:

    • 感谢您的回答。在我的情况下,前两个选项是不可能的,我不得不选择最后一个选项。但是当谈论文本对象时,您是指 BT 中的 Tj 和 TJ 吗?还是您的意思是包含流-BT-的内容对象? cm、q 和 Q 用于对内容对象中的 BT 进行排序,还是对内容对象“页面”进行排序?在我的情况下,包含流的内容对象至少到目前为止是按照正确的顺序排列的(第 2 页在第 1 页之后)。我关心的排序是内容对象中的顺序,如何对 BT 和其中的 Tj/J 进行排序?
    • 如果我只考虑 Tm、Td、TD 和 T* 而没有更多信息,是否可以订购它们?对于第二个问题,否,内容对象仅被一个页面引用,但该内容包含属于它所引用的页面和下一个页面的 BT。所以下面的页面引用了另一个内容对象。
    • "但是当谈到文本对象时,您的意思是" - 根据规范,PDF 文本对象BT 启动 并由 ET 终止,请参阅 ISO 32000-1,第 9.4.1 节。 “在我的例子中,包含流的内容对象按正确的顺序排列(第 2 页在第 1 页之后)至少到现在为止” - 你是什么意思?我希望您找到指定的页面,即通过 Pages 树,然后从那里访问页面 Contents,不要盲目寻找可能是内容流的流在文件中,希望它们一页一页地出现......
    • “如果我只考虑 Tm、Td、TD 和 T 而没有更多信息,是否可以订购它们?”* - 如果您只考虑它们(当然还有前面的文本显示指令的进步),您只能对文本块文本对象中进行排序,并且必须对整个文本对象的顺序做出假设。 “但是该内容包含属于它所引用的页面和后续页面的 BT。” - 你的意思是有文本显示说明绘制文本你在相关页面上找不到?那么该文本只是在页面上不可见,但它就在那里。
    • 请提供示例 PDF 来说明您遇到的问题 - 仅从您的描述来看,我只是对可能存在的问题有一个非常模糊的印象。
    猜你喜欢
    • 2019-12-05
    • 2016-04-22
    • 2015-08-17
    • 1970-01-01
    • 2010-12-05
    • 2011-10-23
    相关资源
    最近更新 更多