所有 PDF 都先跑 OCR?
先判断文字层
再转换 Markdown
PDF INSPECTION · OCR ROUTING · PYTHON
PDF-INSPECTOR
11 PARTS + PRACTICE
PART 01
认识工具
先检测再解析
PART 04
Python 上手
uv 安装与运行
PART 06
OCR 分流
混合文档处理
手里有一批 PDF,想整理成 Markdown,再交给知识库、RAG 或 AI 助手处理,最先卡住的往往是文字能不能干净地取出来。模型选择反而要排在后面。
同样是 PDF,有的可以直接复制文字,有的整页都是扫描图片,还有一些只有部分页面需要 OCR。如果不做判断,全部送去 OCR,速度慢、成本高,原本清楚的文字也可能被识别错。
开源项目 pdf-inspector 解决的正是这一步:先在本地检查 PDF 类型,再提取已有文本,并尽量还原标题、列表、表格和阅读顺序。需要 OCR 的页面会被单独标出来。
这篇文章用 Python 跑一遍完整流程。做完后,你会得到一份 Markdown,并知道哪些页面还需要交给 OCR。
01
PART
pdf-inspector 是什么
OVERVIEW · TOOL POSITIONING
pdf-inspector 是 Firecrawl 开源的 PDF 分类和文本提取工具,核心用 Rust 编写,采用 MIT 许可证。
它不依赖大模型,也不会把文件上传到外部服务。解析工作在本地完成,适合报告、论文、合同、说明书、财务文档等包含原生文字的 PDF。
它主要做两件事:
判断 PDF 是文本型、扫描型、图片型还是混合型。
从文本型页面提取内容,并转换成结构化 Markdown。
官方同时提供 Python、Node.js、Rust、命令行和浏览器 WebAssembly 接口。个人处理文档,用 Python 最容易上手;要接入网页或 Node 服务,也有现成的 npm 包。
02
PART
为什么先判断,再决定是否 OCR
ROUTING · COST CONTROL
文本型
直接本地提取
混合型
按页调用 OCR
扫描型
进入 OCR 流程
很多 PDF 工具一看到文件,就直接把每一页渲染成图片,再执行 OCR。这条路线通用,但会带来几个实际问题。
一份 100 页的报告,可能只有封面和两张附件是扫描件。若整份文件都执行 OCR,等待时间和服务费用会明显增加。文字型页面原本包含准确字符,经过 OCR 后,数字、小数点、代码和专有名词反而可能出错。
pdf-inspector 会检查页面内容流中的文字与图片操作符,并返回:
PDF 类型;
判断置信度;
总页数;
需要 OCR 的页码;
字体编码是否异常;
文档是否包含表格或多栏布局。
这样就能把文档分成两条路线:有可靠文本层的页面直接本地提取,扫描页或乱码页再送入 OCR。
对批量文档系统来说,这个“分流器”通常比再换一个更贵的 OCR 服务更有用。
03
PART
它能把哪些内容转成 Markdown
OUTPUT · DOCUMENT STRUCTURE
普通的 PDF 文本提取,经常只返回一长串文字。双栏论文左右交叉,表格变成散乱数字,标题也和正文混在一起。
pdf-inspector 会读取文字位置、字体大小和样式,再尝试恢复文档结构,包括:
根据字号识别 H1 到 H4 标题;
识别项目符号、数字列表和字母列表;
保留粗体、斜体、链接与代码块;
处理多栏页面的阅读顺序;
识别带边框和按文字对齐形成的表格;
过滤页码,合并断行单词;
发现字体编码损坏时,提示改用 OCR。
这里的关键词是“尝试恢复”。PDF 记录的是页面上每个字符放在哪里,并没有统一保存“这是二级标题”“这是表格第三列”之类的语义。版式越特殊,后续人工检查越重要。
04
PART
用 uv 安装 Python 版本
TUTORIAL · PYTHON SETUP
先进入自己的 Python 项目目录。如果还没有项目,可以执行:
uv init pdf-reader
cd pdf-reader
安装 pdf-inspector:
uv add pdf-inspector
官方提供了 Windows x64、macOS 和常见 Linux 平台的预编译包。大多数电脑不需要单独配置 Rust。若使用未提供预编译包的平台,安装过程才可能要求本机具备 Rust 工具链。
在项目根目录放入一份 document.pdf,然后新建 inspect_pdf.py。
from pathlib import Path
import pdf_inspector
pdf_path = Path("document.pdf")
result = pdf_inspector.process_pdf(str(pdf_path))
print(f"PDF 类型:{result.pdf_type}")
print(f"总页数:{result.page_count}")
print(f"置信度:{result.confidence:.2f}")
print(f"需要 OCR 的页码:{result.pages_needing_ocr}")
print(f"存在编码问题:{result.has_encoding_issues}")
if result.markdown:
output_path = pdf_path.with_suffix(".md")
output_path.write_text(result.markdown, encoding="utf-8")
print(f"Markdown 已保存到:{output_path}")
else:
print("没有提取到可用文字,请对相应页面执行 OCR。")
运行脚本:
uv run python inspect_pdf.py
如果原文件是文本型 PDF,同目录下会生成 document.md。打开后先检查标题层级、表格和多栏内容,不要直接把结果批量写入正式知识库。
05
PART
只检测 PDF,不提取全文
DETECTION · FAST CHECK
有些系统只需要判断“是否应该调用 OCR”,没必要先转换整份文档。此时可以使用 detect_pdf:
import pdf_inspector
result = pdf_inspector.detect_pdf("document.pdf")
print(result.pdf_type)
print(result.confidence)
print(result.pages_needing_ocr)
官方文档中,detect_pdf 返回的 pages_needing_ocr 使用从 1 开始的页码,更适合直接给人查看。部分更底层的分类接口使用从 0 开始的页码,接入代码时要确认清楚,避免把 OCR 发到相邻页面。
06
PART
混合 PDF 怎么处理
WORKFLOW · HYBRID PDF
生产场景里,更常见的是混合 PDF:正文可以提取,附件却是扫描图。
可以先执行完整解析,保存已经提取到的 Markdown,再把 pages_needing_ocr 中的页面交给 OCR。OCR 返回文字后,根据页码插回原文档。
一个简单的路由判断可以这样写:
import pdf_inspector
result = pdf_inspector.process_pdf("document.pdf")
if result.pdf_type == "text_based" and not result.has_encoding_issues:
print("直接使用本地提取结果")
elif result.pdf_type == "mixed":
print(f"仅对这些页面执行 OCR:{result.pages_needing_ocr}")
else:
print("这份文件更适合走 OCR 流程")
实际项目还应检查置信度、空文本、乱码和页面布局。不要只用一个 pdf_type 字段决定所有后续操作。
07
PART
命令行用户可以直接用 pdf2md
CLI · AUTOMATION
如果已经安装 Rust,也可以使用项目自带的命令行工具:
cargo install pdf-inspector
pdf2md document.pdf
只输出 Markdown:
pdf2md document.pdf --raw
处理指定页面:
pdf2md document.pdf --select-pages 1,3,5-10
只判断文档类型:
detect-pdf document.pdf --json
命令行方式适合脚本、自动化任务和服务器管道。Python 用户没有必要为了这几个命令额外安装 Rust,直接使用 Python 包即可。
08
PART
Node.js 和浏览器也能接入
INTEGRATION · NODE AND WASM
Node.js 项目可以安装官方 npm 包:
npm install @firecrawl/pdf-inspector
最小调用示例:
import { readFileSync } from "node:fs";
import { processPdf } from "@firecrawl/pdf-inspector";
const pdf = readFileSync("document.pdf");
const result = processPdf(pdf);
console.log(result.pdfType);
console.log(result.pagesNeedingOcr);
console.log(result.markdown);
这个包为 Windows x64、macOS ARM64 和常见 Linux 环境提供预编译二进制文件。浏览器项目则可以使用 @firecrawl/pdf-inspector-wasm,让 PDF 留在用户设备中解析,不必先上传服务器。
09
PART
官方基准怎么看
BENCHMARK · READ CAREFULLY
0.875
综合得分
0.470s
200 份文档
M4 Pro
项目方测试
项目 README 公布了一组基于 200 份 PDF 的本地解析测试,关闭了 OCR 和模型解析。在该测试中,pdf-inspector 的综合得分为 0.875,200 份文档的完整运行时间为 0.470 秒。
这组数据由项目方在 Apple M4 Pro 上测得,测试结果和复现分支已经公开。它能说明工具在该数据集上的速度与结构恢复能力,但不能直接推导到所有中文合同、复杂财报或超大 PDF。
更稳妥的做法是拿自己的文档抽样测试。至少准备以下几类文件:
普通文字报告;
双栏论文;
带合并单元格的财务表格;
扫描合同;
文字页和扫描附件混合的 PDF。
记录提取时间、乱码页数、表格可用率和需要人工修正的段落,再决定是否接入正式流程。
10
PART
哪些情况不要只靠它
LIMITS · OCR REQUIRED
能力边界
扫描页、手写内容、图表信息和损坏字体仍要交给 OCR 或视觉模型处理。
pdf-inspector 没有内置 OCR。整页扫描、手写内容、低清照片和没有文字层的图片型 PDF,仍然需要 OCR。
下面几种文档也要谨慎:
数学公式很多的论文;
图表、流程图承担主要信息的报告;
字体映射损坏或加密受限的文件;
版面极不规则的宣传册;
需要像素级还原的发票和票据。
它输出 Markdown,不等于理解图像。图表中的趋势、扫描页上的印章、图片里的文字,都需要视觉模型或 OCR 补充。
///
LAST
适合放进哪些工作流
PRACTICE · FINAL ADVICE
如果你正在搭建以下系统,pdf-inspector 很值得先做一轮测试:
把论文和报告批量整理成 Markdown;
为 RAG 知识库清洗 PDF;
给 AI 助手准备可检索的本地资料;
从合同和财务文档中保留表格结构;
在上传 OCR 服务前筛掉不需要识别的页面;
在浏览器内完成隐私敏感文档的初步解析。
个人用户最简单的方案是:先用 process_pdf 生成 Markdown,检查 pages_needing_ocr,只有确实缺少文字的页面才调用 OCR。
这条流程没有把所有 PDF 问题一次解决,但它把昂贵、缓慢的 OCR 留给真正需要的页面。面对一批来源复杂的 PDF,这一步往往能省下最多时间。
我是dennis
觉得这篇教程有用,可以点赞、在看或转发给正在处理 PDF 的朋友。
THANKS FOR READING
夜雨聆风