pdf-inspector:PDF 秒变 Markdown
PDF 是知识管线里最不听话的格式。文本能选中复制,但阅读顺序是乱的;表格长得像图形;标题只有字号没有层级。白物集的知识卡片管线每天处理 PDF 来源,踩过整本 OCR 的坑之后,结论很明确:先分类,再决定要不要上 OCR。pdf-inspector 就是干这个的。
pdf-inspector 是 Firecrawl 开源的 Rust 库,GitHub 14740 stars,MIT 协议。它的定位是 PDF 分类与文本提取:10-50ms 判断一份 PDF 是文本型、扫描型、图片型还是混合型,文本型的直接在本地转成结构化 Markdown,全程不调用 OCR 服务。Firecrawl 之前在白物集推荐过网页抓取服务,这次是它家的另一个独立开源库,走完全不同的技术栈。
它解决什么问题
Firecrawl 在自建抓取管线时统计过一个数据:约 54% 的 PDF 自带文本层,根本不需要 OCR。无差别把每一份 PDF 送 OCR,浪费的是时间和钱。pdf-inspector 的思路是先花 10-50ms 分类,文本型的本地直接提取,扫描型的返回待 OCR 页码清单,只把需要的几页送出去。
这个分类能力是它和传统提取库(PyMuPDF、pdfplumber)最本质的区别。传统库默认「这份 PDF 有文本层」,遇到扫描版直接产出空文本或乱码;pdf-inspector 默认「先确认它是什么,再决定怎么处理」。
三个核心亮点
1. 分类 + 逐页 OCR 路由。 detect_pdf 返回 pdf_type(text_based / scanned / image_based / mixed)、置信度 confidence、pages_needing_ocr 页码清单,以及 ocr_reasons_by_page——每一页为什么需要 OCR,原因都是机器可读的标识符。这个设计可以直接接进自动化管线做分流,不需要人工翻 PDF。
2. 中文 PDF 的 CID 字体解码。 中文论文和扫描转出的 PDF 大量使用 Type0 / Identity-H 内嵌字体,很多提取工具遇到这类字体直接吐乱码。pdf-inspector 用 ToUnicode CMap 解码,覆盖 UTF-16BE、UTF-8、Latin-1 编码,同时自动标记损坏的字体编码,提示调用方回退 OCR。对中文知识库场景,这一条比速度更重要。
3. 表格与阅读顺序。 转 Markdown 时标题按字号比例映射 H1-H4,表格用「PDF 绘图指令 + 文本对齐启发式」双模式检测,多栏排版按阅读顺序重排。在 opendataloader-bench 基准(200 份 PDF,关闭 OCR)上,综合分 0.875,阅读顺序 0.915,表格 0.814;200 份全部处理耗时 0.470s。对照组里 PyMuPDF4LLM 耗时 17.117s,MarkItDown 16.165s。基准由官方于 2026 年 7 月 31 日在 Apple M4 Pro 上更新,完整方法和版本号在 README 中可复现。
白物集实际怎么用到
白物集智驾场景的知识卡片库建过一次真实的「整本 OCR」:一本 247 页的扫描版教材,逐页 OCR 校对建卡,实测约 2 页/秒,还得断点续跑。那次经历让管线对 OCR 成本有了切身体会——扫描版确实避不开,但日常收到的论文、白皮书、行业报告大多数自带文本层,无差别走 OCR 是浪费。
白物集管线的改造方向是:PDF 进库前先过一遍 detect_pdf,文本型的本地转 Markdown 直接入库,只有扫描型才走 OCR。pdf-inspector 补的是分类和文本型提取这一环;扫描型 PDF 它不做 OCR,只告诉你哪些页需要——这是它的设计边界,也是它便宜的原因。
适合什么场景
- 批量把论文、财报、合同、发票转成 Markdown,喂给 LLM 或建知识库
- 需要保留表格结构和阅读顺序的文档处理
- 数据不能出内网的场景:纯本地运行,无 ML 模型、无外部服务,只依赖一个 lopdf 解析库
- 浏览器端处理:官方提供 WebAssembly 版本,可以在浏览器里跑,不需要服务器
不适合:扫描版 PDF(它不替代 OCR,只负责分类和路由);手写文档;需要还原精确版式的场景。
快速上手
安装:
pip install pdf-inspector
完整处理一条链路:
import pdf_inspector
result = pdf_inspector.process_pdf("paper.pdf")
print(result.pdf_type) # text_based / scanned / image_based / mixed
print(result.markdown) # 结构化 Markdown
det = pdf_inspector.detect_pdf("paper.pdf")
if det.pdf_type != "text_based":
print(det.pages_needing_ocr) # 只把这几页送 OCR
Node 环境执行 npm install @firecrawl/pdf-inspector,浏览器用 WASM 版本。Python 包自带类型声明,接入 CI 无额外成本。
四行代码,把「这份 PDF 要不要上 OCR」从人工判断变成程序判断。下一份 PDF 附件进管线时,值得先跑一次 detect_pdf。