文字能提出来,就算解析成功?
我把五种 PDF交给了它
最后卡在了页码上
从类型判断、逐页提取,到表格校验和页码归属
pdf-inspector 实测记录
8 Parts + Conclusion
PART 01
这次要测什么
类型与页级路由
PART 02
准备5份PDF
顺序与表格校验
PART 03
看它怎样分流
页码坑与结论
从本周周报里的一项“准备真跑”开始,我想确认一件更实际的事。PDF 被提取成文字以后,我还能不能把它准确地找回原位置。
上周周报把 pdf-inspector 列为三个准备真跑的项目之一。周报里我先记录了它在速度、阅读顺序和表格还原上的公开结果,现在用本机样本把这几个问题跑一遍。
开始之前先把工具边界说清楚。pdf-inspector 负责 PDF 分类和原生文字提取,它会告诉我文件属于原生文字、纯扫描还是混合类型,列出需要 OCR 的页码,并把有文字层的页面整理成 Markdown。到这里,它解决的是“能不能读出文字”。还要继续检查,文字顺序、表格单元格和页码归属能不能跟着保留下来。
周报里的 200 份 PDF 是项目方公开基准,本文的五份文件则是我为了逐项核对而用ai工具生成的控制样本,两组结果不直接横向比较。
我真正想补上的答案是,文字提取完成以后,页码、阅读顺序和上下文是否还在。如果后面要做检索、问答或审计,单纯得到一段能读的 Markdown 还不够。用户问某个问题时,程序需要把答案带回原页,才有复核的可能。
所以我把本次实测的重点放在“能不能回到原页”这个问题上。将这五份结构不同的 PDF喂给它,先看它怎样分类和分流,再看文本顺序和表格,最后专门追踪页码线索在哪里变少。
下面我直接按这次实测的过程往下写。先准备样本,再跑命令、核对结果,碰到差异就停下来查,最后再看这些结果该怎么放进实际流程。希望看完这个实测你能有所收获。
01
PART
这次我到底要测什么
PART 01 · FIELD NOTES
开始之前先把目标写下来,避免跑到最后只剩下一张“成功”的截图。
先把工具边界说清楚。pdf-inspector 是本地 PDF 分类和文本提取工具,可以判断原生文字页、扫描页和混合页,也能返回需要 OCR 的页码。它不负责把图片里的文字识别出来,OCR 仍然要交给后续流程。
第一步,确认工具能不能区分原生文字页、扫描页和混合 PDF。
第二步,确认中文文本和双栏文字有没有丢失或交错。
第三步,把报表拆成单元格逐项比较,再检查每页的页首信息是否跟着页面走。
最后,用逐页 API 和整份 Markdown 各做一次查询,看看两种结果对页码任务有什么影响。
这组测试只回答固定结构上的行为,不负责推导所有业务 PDF 的总体准确率。为了让每个结果都能核对,我给每份样本写了独立锚点和真值文件。测试完成以后,我还用 SHA-256 锁定输入文件,避免换了一份样本却继续沿用旧结论。
02
PART
我准备了五份可核对的 PDF
PART 02 · FIELD NOTES
这五份文件都是我在本机用ai工具按测试目的生成的控制样本,内容不含个人信息,也没有使用第三方受限页面。它们分别对应五种我想观察的情况。
我没有把样本做成一眼就能看出的失败案例。而是每页都放了不同的锚点、日期或金额。工具必须把它们放回正确的页面,我才把结果记为通过。这样做的好处是,测试不会只停留在“输出里有字”上。
03
PART
第一次运行,先看它怎样分流
PART 03 · FIELD NOTES
我在本机上完成测试,Python 版本为 3.14.6,pdf-inspector 为 1.14.2。每个操作执行 11 次,第一次作为预热,后 10 次取中位数。
如果机器上已经有 Python 环境,最小调用可以从这里开始。
先把版本和目录说明白。下面两行只负责准备这次测试的运行环境,第一行安装指定版本的 pdf-inspector,第二行进入我存放五份样本、真值文件和运行脚本的测试目录。pdf-inspector-test 是示例目录名;它不是 pdf-inspector 的安装目录,也不会在这一步读取 PDF。
python -m pip install pdf-inspector==1.14.2cd pdf-inspector-test
环境准备好以后,我用一份中文长文档跑最小调用。代码按三个层次取结果:detect_pdf 先判断文件类型、页数和待 OCR 页;process_pdf 再取整份 Markdown;extract_pages_markdown 最后返回逐页结果。
这样能把“文件能不能读出来”和“每一页怎样归属”分开检查。
import pdf_inspectorsample = "fixtures/01-chinese-long-document.pdf"info = pdf_inspector.detect_pdf(sample)print(info.pdf_type, info.page_count, info.pages_needing_ocr)document = pdf_inspector.process_pdf(sample)print(document.markdown[:80] if document.markdown elseNone)pages = pdf_inspector.extract_pages_markdown(sample)for page in pages.pages:print(page.page, page.needs_ocr, len(page.markdown))
先看分类结果,再决定后面该用哪一种输出。
01-chinese-long-document.pdf text_based 24 []02-two-column-reading-order.pdf text_based 4 []03-multipage-financial-table.pdf text_based 6 []04-scan-only.pdf scanned 5 [1, 2, 3, 4, 5]05-mixed-text-and-scan.pdf mixed 6 [2, 4, 6]
这里有一个页码口径需要先说明。pages_needing_ocr 使用 PDF 常见的 1-based 页码,例如 [2, 4, 6] 就是第 2、4、6 页;逐页结果里的 page.page 使用从 0 开始的索引,第一页记为 0。因此,本文提到的“第 4 页”和“第 5 页”均指我们在 PDF 阅读器中看到的页码。
我随后跑了完整测试。终端中的 ./run-evidence.sh 会调用完整测试脚本,打印版本、五份文件的分类和耗时、真值核对结果,以及两个页级查询。截图中的用户名、窗口标题和本地目录已经替换成占位符,命令结构和测试数字保留。

— pdf-inspector 本轮脱敏 Terminal 截图,命令和结果来自同一轮运行
在这组样本里,纯扫描 PDF 调用 process_pdf 的中位耗时是 0.453 ms。这个数字只记录工具完成类型判断和 OCR 路由的时间,不代表图片里的文字已经被识别。真正的 OCR 还要交给后续流程。
04
PART
先看中文和双栏,文字顺序有没有乱
PART 04 · FIELD NOTES
中文长文档有 24 页,每页都有独立的 CN-ANCHOR-Pxx。我把整份 Markdown 中的锚点提出来,和预先写好的 24 个锚点逐一比较,结果是 24/24。这一步说明文字层和锚点都没有缺失,中文长文档的提取结果可以继续往下检查。
我没有把这个结果扩展成“所有中文 PDF 都不会乱码”。这组样本只覆盖了当前的字体和版式,页眉页脚位置也没有在脚本里单独量化。
双栏文档更能检验阅读顺序。我在左栏和右栏分别放了 8 个编号,每页正确顺序应该是 P01-L01 到 P01-L08,再接 P01-R01 到 P01-R08,四页一共 64 个编号。
实际输出和真值完全一致,结果是 64/64。这个数字比总字符数更有意义,因为它能说明解析器有没有把左右两栏交错在一起。

— 双栏 PDF 的原始页面,左右是两条独立的段落流
这里我也确认了一件事。双栏正文和表格不能用同一套判断方式。双栏要看段落的先后,表格要看单元格和页面归属。只看“文本都出来了”,还不足以判断结果能不能继续使用。
双栏结果是 64/64,说明左右两栏没有交错。接下来我把问题换成另一种形态。如果内容被排成表格,解析器能不能同时保住每个单元格,以及它所在的页面?我继续看多页财务表,先核对单元格,再追踪页首信息。
05
PART
财务表先看单元格,再查页首
PART 05 · FIELD NOTES
财务表一共有 6 页、90 行。每行都有记录号、日期、描述、借方、贷方和余额六个单元格。我把 Markdown 每一行拆成六个单元格,去掉单元格首尾空白后,和 CSV 真值逐格比较。结果是 90 行全部匹配,格式错误的表格行是 0,重复交易编号也是 0。
第一页渲染出来的样子很正常。页首有标题、PRETABLE-P01 和统计信息,下面是 15 行表格。

— 财务表 PDF 第 1 页渲染图,页首信息和 15 行表格清晰可见
我原本以为 90 行全部匹配后,这份表格就可以交给检索了。为了确认每一行的上下文没有丢,我又逐页检查了页首。6 页分别有不同的日期、借方合计、贷方合计和页面锚点,这些信息在逐页结果中都对应到了各自的页面。
查完页首以后,我发现 90 行通过还不够。表格解析至少要分两层看。第一层是单元格有没有还原,第二层是这一行属于哪一页。财务文件里,页首期间和合计往往就是解释金额的上下文。只拿到一行金额,后面很容易答不清它属于哪一个期间。
查完页首以后,我确认表格不能只看行数,还要看每一行属于哪一页。这个判断还需要放到更接近真实资料的场景里验证。接下来我把原生文字页和扫描页交替放进同一份 PDF,继续看工具能不能按页分流,以及页码线索会不会在合并结果里变少。
06
PART
混合 PDF 让我踩到了页码坑
PART 06 · FIELD NOTES
混合文档有 6 页,奇数页是原生文字,偶数页是图片。原生页分别写入了不同的案件号、日期和金额,扫描页完全没有隐藏文字层。
逐页结果很干净。原生页 1、3、5 没有被送去 OCR,扫描页 2、4、6 都出现在 pages_needing_ocr。3 个原生页的案件字段也全部匹配。

— 混合 PDF 第 5 页渲染图,原生文字页带有独有案件字段
页码问题是在后面的查询里冒出来的。我查财务表第 4 页时,TXN-0046 还在,PRETABLE-P04 却不见了。我又用逐页 API 查了一次,缺少的页首锚点重新出现。查询财务表第 4 页时,整份 Markdown 命中 2/3,逐页 API 命中 3/3。混合文档第 5 页也出现同样的差异,整份 Markdown 是 3/4,逐页 API 是 4/4。这里的“命中”是对真值文件中的字段做精确字符串包含判断,不代表完整检索系统的召回率。
| PRETABLE-P04 | PRETABLE-P04 | |||
| MIXED-NATIVE-P5 | MIXED-NATIVE-P5 |
财务表第 4 页的逐页结果里,能看到这一段。
## PRETABLE-P04Reporting period 2026-08-15 to 2026-08-29|TXN-0046|2026-08-15|Batch service 10|2652.00|0.00|238153.00|
后来回看了整份 Markdown。表格行和期间仍然存在,只是重复出现的页首锚点没有全部保留下来。它读起来更短,却不适合承担页码定位。这里的结果不能简单归为“解析失败”,更准确的说法是,整份 Markdown 和逐页 API 适合不同任务。

— 本轮测试的通过项和整份 Markdown 的页级边界
07
PART
吧测试结果放回真实流程里
PART 07 · FIELD NOTES
到这里,问题已经从“有没有解析出来”变成了“后续流程该保存哪种结果”。我把这次页码差异放回实际使用场景,重新整理一遍我会保留的中间结果,以及它们分别适合什么任务。
这次踩坑以后,我不会只保存一份合并后的 Markdown,而是会保留原始 PDF、检测结果和逐页 Markdown。
如果只是快速阅读,我会优先看 process_pdf 的整份 Markdown。如果任务需要回答“第几页”“这笔金额属于哪个期间”,还是要使用逐页 API,并把页码和文件哈希一起写进索引。扫描页进入 OCR 后,我还会标记它是 OCR 结果,方便在数字识别有疑问时回看原图。
耗时也要放回到样本规模里看。中文长文档的 process_pdf 中位耗时是 11.645 ms,双栏文档是 1.590 ms,财务表是 6.069 ms,纯扫描样本只做结构检测,耗时是 0.453 ms。
下图和终端截图来自同一轮运行,图中还列出了 detect_pdf 和逐页 API 的中位耗时。只能当成本机这组样本的记录,不拿来做跨工具排名。

— 五种 PDF 的检测、整文档处理和逐页 API 中位耗时
最后,我也把这轮测试的边界写清楚。本次测试没有覆盖倾斜扫描页、低清晰度 OCR、合并单元格、脚注、复杂跨页表格、加密 PDF 和多语言混排。五份样本都是我为了控制变量使用ai工具生成的,没有专门构造失败文件,所以这次结果只能说明它在这些固定场景里的表现,不能用来推导真实业务 PDF 的失败率。
08
PART
总结
PART 08 · FIELD NOTES
这轮自建样本里,中文文本锚点、双栏阅读顺序和简单表格单元格都通过了真值核对,混合文档的原生页和待 OCR 页也能按页区分。基于这些结果,在实际使用时我会选择把 pdf-inspector 放在 PDF 进入后续流程前,作为第一道类型判断和页级路由检查。它负责告诉我文件属于哪种类型,哪些页面需要进入 OCR,整份 Markdown 和逐页结果则分别用于阅读和页码定位。
这次实测给我的收获有三点。
PDF 转成 Markdown 以后,文字能不能读只是起点,页码和上下文能不能跟着走同样重要。
整份 Markdown 适合阅读,逐页结果更适合检索、引用和审计。
需要 OCR 只代表页面进入了下一步,不代表图片里的文字已经识别正确。
这次实测之后,我给自己留下了一套更稳的判断顺序。先用带独立锚点的样本把 PDF 类型分清,再逐项检查阅读顺序、表格单元格和页面归属。看到一份读起来很顺的 Markdown,我还会多问一句,里面的答案能不能准确回到原始 PDF 的那一页。
我是开源仓库猎人,专注于发现 GitHub 上的热门开源项目,不只是罗列,更想说清楚它们在往哪个方向走。每周一三五深度解读,周日盘点十大热点。
既然看到这里了,如果觉得有收获,周五我会继续实测 PI from Scratch,看看它能不能把从零开始的过程讲清楚
THANKS FOR READING
谢谢你看我的文章,我们周五见。
测试声明
STATEMENT
环境
• 测试日期为 2026 年 8 月 17 日~ 8月18日。
• Python 为 3.14.6,pdf-inspector 为 1.14.2。
• 每个操作执行 11 次,第一次作为预热,耗时取后 10 次的中位数。
样本与数据
• 五份 PDF 都是用ai工具新生成的测试材料,内容不含个人信息,也没有使用第三方受限页面。
• 中文文档有 24 页,双栏文档有 64 个顺序锚点,财务表有 90 行,混合文档有 3 个原生页字段。
• 输入文件、真值文件、逐页 Markdown、运行 JSON 和 SHA-256 清单保存在本机测试目录。
边界与图片
• 本文验证了 PDF 类型判断、页级 OCR 路由、原生文本提取、双栏顺序和简单表格单元格匹配。
• 本文没有把“需要 OCR”写成 OCR 识别准确,也没有覆盖合并单元格、脚注、复杂跨页表格和真实业务 PDF 的总体准确率。本轮是受控样本验证,不给出总体成功率。
• 终端截图来自本轮真实命令输出,只对窗口标题和目录路径做了遮挡。PDF 页面图和耗时图来自本轮测试文件与运行结果。
AI说明
• 本文整理过程使用了 AI 辅助。测试任务、生成脚本、命令结果和截图来自本机实际运行。
• 本文与 pdf-inspector 项目维护方不存在合作或背书关系。产品名称和商标归各自权利人所有。
延伸阅读
MORE TO READ
▣《DeepSeek Harness 实测:从安装启动到插件复用,一次失败测试如何跑通》
周一实测的文章,记录我从安装启动、工具准入到插件复用的完整过程。
▣《DeepSeek Harness 已超 10 万 Star,本周 10 个 GitHub 热门项目我准备真跑 3 个》
上周周报,pdf-inspector 被列为三个准备真跑的项目之一。文中先整理了项目背景和公开基准,同时说明了真实实测计划。
▣《Reasonix 配上 DeepSeek 到底怎样?我拿同一项目和 OpenCode 实测了三轮》
同一系列的另一篇实测,我把两套 Agent 接到同一模型路由,连续改了三轮,重点看如何设计可核对的验收条件
夜雨聆风