从PDF中提取文本

Extracting text from PDF

本文关键字:取文本 提取 PDF      更新时间:2023-10-16

我正在尝试使用这里找到的代码从PDF文件中提取文本。代码使用了zlib库。

AFAICT程序通过查找pdf文件中文本"stream"answers"endstream"出现之间的内存块来工作。然后使用zlib对这些块进行充气。

代码在一个示例pdf文档上工作得很好,但在另一个示例文档上,似乎zlib的inflate()函数每次调用时都返回-3 (Z_DATA_ERROR)。

我注意到,失败的pdf文件被设置为在Adobe阅读器中打开时没有"复制"选项。这可能与inflate()错误有关吗?如果是,有没有办法解决这个问题?

下面的代码片段-参见注释

            //Now use zlib to inflate:
            z_stream zstrm; ZeroMemory(&zstrm, sizeof(zstrm));
            zstrm.avail_in = streamend - streamstart + 1;
            zstrm.avail_out = outsize;
            zstrm.next_in = (Bytef*)(buffer + streamstart);
            zstrm.next_out = (Bytef*)output;
            int rsti = inflateInit(&zstrm);
            if (rsti == Z_OK)
            {
                int rst2 = inflate (&zstrm, Z_FINISH); // HERE IT RETURNS -3
                if (rst2 >= 0)
                {
                    //Ok, got something, extract the text:
                    size_t totout = zstrm.total_out;
                    ProcessOutput(fileo, output, totout);
                }
            }

EDIT:我通过名为zamzar的在线pdf-to-text转换器测试了从"加密"pdf中提取文本,得到的文本文件非常完美。所以zamzar要么有超级解密系统…又或者这并不难。

EDIT:刚刚发现A-pdf也转换成文本没有问题

PDF格式的流不需要使用flat编码。它们可以被编码为:

    没有
  1. LZW
  2. ASCII85
  3. Crypt(可能是几种不同的算法之一)

而且(惊讶,惊讶)这些方法中的任何一种都可以相互叠加!

如果没有复制选项,则有可能使用所有者密码而没有用户密码进行加密。这允许作者创建应该被读者尊重的访问权限,包括:

  1. 修改文档内容
  2. 复制文本/图形
  3. 添加/编辑注释
  4. 打印
  5. 形式填写
  6. 组装文档(插入、删除页面、创建书签、缩略图)
  7. 高/低质量打印

这种从PDF中获取文本的特殊方法充满了错误,我可以为您提供一组您无法使用您的方法处理的文档,因为字体重新编码、文本分割、奇怪的位置、表单xobject、不寻常的转换等等。

要正确地做到这一点,您需要一组更好的工具,这些工具不会对PDF文档的实际格式和结构视而不见。iText会做这个,DotImage会做这个

为了让您了解问题的范围,我在Acrobat 1.0中编写了原始文本搜索代码,并使用了我可用的所有内部工具,花了几个月的时间才使其正确,代码包括查找不寻常的、非直线方向的文本(想想地图)、处理连接、重新编码、非罗马字体等功能。当我在编写这些代码时,另一位工程师花了几年的时间全职编写名为Wordy的代码,以完成类似(但更复杂)的全文提取和索引(有关Wordy的更多信息,请参阅此回答)。

如果没有"copy"选项,那么pdf和流都是加密的。普通的zlib将不起作用,你必须先解密pdf,现在你在它使用一个适当的库来提取文本,有很多编码需要注意,不是所有的都是win ansi。

这是可能的,因为文档的头不同,关于这一点,请参阅相关问题ZLib充气()失败-3 Z_DATA_ERROR