如何进一步处理 Tika / PDFBox 无法解析但 Evince / Libre Office Draw 可以解析的错误/格式错误的 PDF?
How to further process a buggy / malformed PDF that cannot be parsed by Tika / PDFBox but can by Evince / Libre Office Draw?
我的程序正在使用 Tika 2.24 读取文档以提取其内容。
尽管 Evince、Libre Office Draw 甚至 Gimp 可以打开它们,但有些 PDF(可能有错误或格式错误)无法由 PDFBox 处理。
我无法共享这些 PDF,但我可以说的是,它们曾经使用 PDFBox 2.0.25 触发 a Whosebug Error as described on Jira,现在使用 PDFBox 2.0.26 触发 IOException :
Caused by: java.io.IOException: Possible recursion detected when dereferencing object 29 0
因此,现在可以捕获 IOException,很容易尝试以不同于触发 IOException 的第一次解析的方式处理格式错误的 PDF。
我通过在解析器上设置 setLenient(true)
来阅读 ,但找不到在 Tika 中设置这种宽大处理的方法。
顺便说一下,我在 之后使用了两个 setLenient(true and false)
,但 IOException 仍然出现。
编辑:按照 KJ 的建议我 运行 pdftotext 输出以下警告:
Syntax Error (5602): Object '29 0 obj' is being already parsed
Syntax Error (5603): Bad 'Length' attribute in stream
Syntax Error (8596): Missing 'endstream' or incorrect stream length
Syntax Error (16945): Object '35 0 obj' is being already parsed
Syntax Error (16946): Bad 'Length' attribute in stream
Syntax Error (23267): Missing 'endstream' or incorrect stream length
Syntax Error (23332): Object '37 0 obj' is being already parsed
Syntax Error (23333): Bad 'Length' attribute in stream
Syntax Error (28645): Missing 'endstream' or incorrect stream length
(请注意:有 4 个页面似乎格式不正确,因为 PDFSam 无法单独导出它们)。
按照 KJ 的建议在文本编辑器中打开 pdf 文件只显示了一个“29 0 obj”的匹配项。使用 mutool show -be mypdf.pdf 29
输出 warning: PDF stream Length incorrect
然后是压缩内容。
[QPDF校验]
仍然遵循 KJ 的建议,运行 QPDF with check
flag yields:
checking myPDFWithIssues.pdf
PDF Version: 1.5
File is not encrypted
File is not linearized
WARNING: myPDFWithIssues.pdf (offset 5602): loop detected resolving object 29 0
WARNING: myPDFWithIssues.pdf (object 29 0, offset 5552): /Length key in stream dictionary is not an integer
WARNING: myPDFWithIssues.pdf (object 29 0, offset 5603): attempting to recover stream length
WARNING: myPDFWithIssues.pdf (object 29 0, offset 5603): recovered stream length: 2983
WARNING: myPDFWithIssues.pdf (offset 16945): loop detected resolving object 35 0
WARNING: myPDFWithIssues.pdf (object 35 0, offset 16895): /Length key in stream dictionary is not an integer
WARNING: myPDFWithIssues.pdf (object 35 0, offset 16946): attempting to recover stream length
WARNING: myPDFWithIssues.pdf (object 35 0, offset 16946): recovered stream length: 6311
WARNING: myPDFWithIssues.pdf (offset 23332): loop detected resolving object 37 0
WARNING: myPDFWithIssues.pdf (object 37 0, offset 23282): /Length key in stream dictionary is not an integer
WARNING: myPDFWithIssues.pdf (object 37 0, offset 23333): attempting to recover stream length
WARNING: myPDFWithIssues.pdf (object 37 0, offset 23333): recovered stream length: 5302
然而,错误的 PDF 已被另一个用户(来自相同来源)重新生成,并且较新的 PDF 没有显示任何警告。所以问题很难追踪!
所以我的问题是:如何使用 Tika / PDFBox 处理格式错误的 PDF,这些 PDF 会触发上述与可能的递归相关的 IOException?
感谢任何提示
我采用的快速而肮脏的方法是使用外部命令行工具 pdftotext
(来自 Debian 上的包 poppler-utils
/ Ubuntu),正如@KJ 在他们的(现在删除)评论。
我的程序正在使用 Tika 2.24 读取文档以提取其内容。
尽管 Evince、Libre Office Draw 甚至 Gimp 可以打开它们,但有些 PDF(可能有错误或格式错误)无法由 PDFBox 处理。
我无法共享这些 PDF,但我可以说的是,它们曾经使用 PDFBox 2.0.25 触发 a Whosebug Error as described on Jira,现在使用 PDFBox 2.0.26 触发 IOException :
Caused by: java.io.IOException: Possible recursion detected when dereferencing object 29 0
因此,现在可以捕获 IOException,很容易尝试以不同于触发 IOException 的第一次解析的方式处理格式错误的 PDF。
我通过在解析器上设置 setLenient(true)
来阅读
顺便说一下,我在 setLenient(true and false)
,但 IOException 仍然出现。
编辑:按照 KJ 的建议我 运行 pdftotext 输出以下警告:
Syntax Error (5602): Object '29 0 obj' is being already parsed Syntax Error (5603): Bad 'Length' attribute in stream Syntax Error (8596): Missing 'endstream' or incorrect stream length Syntax Error (16945): Object '35 0 obj' is being already parsed Syntax Error (16946): Bad 'Length' attribute in stream Syntax Error (23267): Missing 'endstream' or incorrect stream length Syntax Error (23332): Object '37 0 obj' is being already parsed Syntax Error (23333): Bad 'Length' attribute in stream Syntax Error (28645): Missing 'endstream' or incorrect stream length
(请注意:有 4 个页面似乎格式不正确,因为 PDFSam 无法单独导出它们)。
按照 KJ 的建议在文本编辑器中打开 pdf 文件只显示了一个“29 0 obj”的匹配项。使用 mutool show -be mypdf.pdf 29
输出 warning: PDF stream Length incorrect
然后是压缩内容。
[QPDF校验]
仍然遵循 KJ 的建议,运行 QPDF with check
flag yields:
checking myPDFWithIssues.pdf
PDF Version: 1.5
File is not encrypted
File is not linearized
WARNING: myPDFWithIssues.pdf (offset 5602): loop detected resolving object 29 0
WARNING: myPDFWithIssues.pdf (object 29 0, offset 5552): /Length key in stream dictionary is not an integer
WARNING: myPDFWithIssues.pdf (object 29 0, offset 5603): attempting to recover stream length
WARNING: myPDFWithIssues.pdf (object 29 0, offset 5603): recovered stream length: 2983
WARNING: myPDFWithIssues.pdf (offset 16945): loop detected resolving object 35 0
WARNING: myPDFWithIssues.pdf (object 35 0, offset 16895): /Length key in stream dictionary is not an integer
WARNING: myPDFWithIssues.pdf (object 35 0, offset 16946): attempting to recover stream length
WARNING: myPDFWithIssues.pdf (object 35 0, offset 16946): recovered stream length: 6311
WARNING: myPDFWithIssues.pdf (offset 23332): loop detected resolving object 37 0
WARNING: myPDFWithIssues.pdf (object 37 0, offset 23282): /Length key in stream dictionary is not an integer
WARNING: myPDFWithIssues.pdf (object 37 0, offset 23333): attempting to recover stream length
WARNING: myPDFWithIssues.pdf (object 37 0, offset 23333): recovered stream length: 5302
然而,错误的 PDF 已被另一个用户(来自相同来源)重新生成,并且较新的 PDF 没有显示任何警告。所以问题很难追踪!
所以我的问题是:如何使用 Tika / PDFBox 处理格式错误的 PDF,这些 PDF 会触发上述与可能的递归相关的 IOException?
感谢任何提示
我采用的快速而肮脏的方法是使用外部命令行工具 pdftotext
(来自 Debian 上的包 poppler-utils
/ Ubuntu),正如@KJ 在他们的(现在删除)评论。