Fast Rust library for PDF inspection, classification, and text extraction. Intelligently detects scanned vs text-based PDFs to enable smart routing decisions.
Access rate limit exceeded. Please log in to continue.
pdf-inspector
用于 PDF 分类与文本提取的快速 Rust 库。默认情况下,它会判断 PDF 是基于文本还是扫描件,提取带位置信息的文本,并在不使用 OCR 的情况下转换为干净的 Markdown。原生 Rust 与 CLI 调用方可选择启用选择性 OCR。提供 Python、Node.js 与 浏览器 WebAssembly 绑定。
由 Firecrawl 构建,用于在本地 200 毫秒内处理文本型 PDF,并为约 54% 无需 OCR 的 PDF 跳过高成本 OCR 服务。
功能
- 智能分类 — 通过采样内容流,在约 10-50 毫秒内识别 TextBased、Scanned、ImageBased 或 Mixed 类型 PDF。返回置信度得分(0.0-1.0)及逐页 OCR 路由。
- 文本提取 — 位置感知提取,提供字体信息、X/Y 坐标,并自动确定多栏阅读顺序。旋转文本片段(页边印章、图表轴标题)保留真实的轴对齐包围盒,并报告其
rotation角度,而不是收缩为零宽度。 - Markdown 转换 — 标题(根据字号比例识别 H1-H4)、无序/有序/字母列表、代码块(等宽字体检测)、表格(基于矩形和启发式方法)、加粗/斜体格式、URL 链接以及分页符。
- 表格检测 — 双模式:基于 PDF 绘图指令的矩形检测,以及基于文本对齐的启发式检测。可处理财务表格、脚注以及跨页续表。
- CID 字体支持 — 针对 Type0/Identity-H 字体的 ToUnicode CMap 解码,支持 UTF-16BE、UTF-8 和 Latin-1 编码。
- 多栏布局 — 自动识别报纸式分栏、顺序阅读顺序,并支持 RTL 文本。
- 编码问题检测 — 自动标记损坏的字体编码,以便调用方回退到 OCR。
- 选择性 OCR — Rust、CLI、Python 和 Node 可仅渲染需要 OCR 的页面,在本地运行 PP-OCRv6 Small,并保留逐页溯源信息及托管回退建议。
- 单次文档加载 — 文档仅解析一次,并在检测与提取之间共享,避免重复 I/O。
- 浏览器 WebAssembly — 在浏览器和 Web Workers 中本地运行同一套 Rust 解析器,内嵌 CMap 且无需服务器往返。
- 默认轻量 — 默认的 Rust 和浏览器构建保持纯提取。原生 Python 和 Node 包包含 OCR 集成,但 PDFium、ONNX Runtime 和模型文件仍为外部依赖,仅当页面被路由到 OCR 时才会被加载。
基准测试
已在 opendataloader-bench 语料库(200 个 PDF)上完成评测。仅展示不采用基于模型的 PDF 解析的本地引擎;评测时禁用了 OCR。分数范围为 0 到 1,越高越好。
| 引擎 | 综合 | 阅读顺序(NID) | 表格(TEDS) | 标题(MHS) | 速度(200 份文档) |
|---|---|---|---|---|---|
| pdf-inspector | 0.875 | 0.915 | 0.814 | 0.788 | 0.470s |
| liteparse | 0.873 | 0.913 | 0.693 | 0.811 | 0.750s |
| opendataloader | 0.831 | 0.902 | 0.489 | 0.739 | 2.569s |
| pymupdf4llm | 0.735 | 0.886 | 0.401 | 0.424 | 17.117s |
| markitdown | 0.589 | 0.844 | 0.273 | 0.000 | 16.165s |
结果已于 2026 年 7 月 31 日在 Apple M4 Pro 上更新。各引擎版本分别为 pdf-inspector 0.2.6、LiteParse 2.10.1、OpenDataLoader 2.2.1、PyMuPDF4LLM 0.2.0 和 MarkItDown 0.1.5。速度指标是在一次不计入统计的预热运行之后,对五个交替或轮换的完整语料库运行结果取中位数;每个解析器都在单个进程中顺序处理文档。
完整的解析器配置、逐文档预测结果、评测器输出以及生成的图表,均可在可复现结果分支中获取。
最佳适用场景: 需要兼顾速度、阅读顺序和表格结构的原生文本 PDF。在本组对比中,pdf-inspector 取得了更高的综合、阅读顺序和表格得分,并且完整运行速度最快。因此,对于需要生成干净、结构化 Markdown,又不希望引入 OCR 延迟或额外基础设施的报告、研究论文、金融文档、发票和法律 PDF,它都是可靠的本地默认选择。
使用配对基准测试工具,在完全相同的语料库与评测器修订版本上比较两个本地构建。
快速开始
Python
pip install pdf-inspector
import pdf_inspector
result = pdf_inspector.process_pdf("document.pdf")
print(result.pdf_type) # "text_based", "scanned", "image_based", "mixed"
print(result.markdown) # Markdown string or None
# Selective OCR; clean text PDFs do not load the external OCR runtime.
ocr = pdf_inspector.process_pdf_with_ocr("document.pdf")
print(ocr.pages_routed_to_ocr)
完整 API 参考:docs/python.md
Node.js
npm install @firecrawl/pdf-inspector
import { readFileSync } from 'fs';
import { processPdf, processPdfWithOcr } from '@firecrawl/pdf-inspector';
const pdf = readFileSync('document.pdf');
const result = processPdf(pdf);
console.log(result.pdfType); // "TextBased", "Scanned", "ImageBased", "Mixed"
console.log(result.markdown); // Markdown string or null
const ocr = await processPdfWithOcr(pdf); // selective OCR, off the event loop
console.log(ocr.pagesRoutedToOcr);
完整 API 参考:napi/README.md
浏览器 WebAssembly
npm install @firecrawl/pdf-inspector-wasm
import init, { processPdf } from '@firecrawl/pdf-inspector-wasm';
await init();
const response = await fetch('/document.pdf');
const pdf = new Uint8Array(await response.arrayBuffer());
const result = processPdf(pdf);
console.log(result.pdfType);
console.log(result.markdown);
完整 API 参考:wasm/README.md
Rust
从 crates.io 安装:
cargo add pdf-inspector
或手动添加:
[dependencies]
pdf-inspector = "1"
use pdf_inspector::process_pdf;
let result = process_pdf("document.pdf")?;
println!("Type: {:?}", result.pdf_type);
if let Some(markdown) = &result.markdown {
println!("{}", markdown);
}
完整 API 参考:docs/rust-api.md
CLI
# Install the CLI tools
cargo install pdf-inspector
# Convert PDF to Markdown
pdf2md document.pdf
# JSON output (for piping), with the document information (title, author, producer, dates, ...)
pdf2md document.pdf --json
# Positioned TextItem JSON (coordinates relative to the visible page box): axis-aligned box, rotation, font, paint (fill and stroke colour, render mode), underline metadata
pdf2md document.pdf --items-json
# Raw markdown only (no headers)
pdf2md document.pdf --raw
# Token-efficient output (collapses long dot leaders and similar source padding)
pdf2md document.pdf --compact
# Insert page break markers (<!-- Page N -->)
pdf2md document.pdf --pages
# Process only specific pages
pdf2md document.pdf --select-pages 1,3,5-10
# Detection only (no extraction)
detect-pdf document.pdf
detect-pdf document.pdf --json
# Detection + layout analysis (tables, columns)
detect-pdf document.pdf --analyze --json
Rust 与 CLI 使用者可在构建时选择启用 OCR:
cargo install pdf-inspector --features ocr --bin pdf2md
PDFIUM_LIB_PATH=/path/to/libpdfium ORT_DYLIB_PATH=/path/to/libonnxruntime \
pdf2md scan.pdf --ocr auto --json
OCR JSON 封装结构采用版本化设计,并报告已路由页面、各页来源与置信度、警告,以及建议进入托管文档流水线的页面。原生 Python 和 Node 包可提供相同流水线,且无需源码构建功能。所有原生入口点仅在启用 OCR 路由时,才需要单独安装的 PDFium 和 ONNX Runtime 库。固定版本下载、平台支持、模型缓存行为以及托管回退集成,请参阅 OCR 运行时配置指南。更底层的控制选项,请参阅 Rust API 指南。
在源码检出环境中,请改用 cargo run --bin pdf2md -- document.pdf 或 cargo run --bin detect-pdf -- document.pdf。
架构
PDF bytes
│
├─► detector → PdfType (TextBased / Scanned / ImageBased / Mixed)
│
└─► extractor
├─ fonts → font widths, encodings
├─ content_stream → walk PDF operators → TextItems + PdfRects
├─ xobjects → Form XObject text, image placeholders
├─ links → hyperlinks, AcroForm fields
└─ layout → column detection → line grouping → reading order
│
├─► tables
│ ├─ detect_rects → rectangle-based tables (union-find)
│ ├─ detect_heuristic → alignment-based tables
│ ├─ grid → column/row assignment → cells
│ └─ format → cells → Markdown table
│
└─► markdown
├─ analysis → font stats, heading tiers
├─ preprocess → merge headings, drop caps
├─ convert → line loop + table/image insertion
├─ classify → captions, lists, code
└─ postprocess → cleanup → final Markdown
文档仅通过 load_document_from_path / load_document_from_mem 加载 一次,并在检测与提取阶段之间共享,因此不会产生重复解析。
项目结构
src/
lib.rs — Public API, PdfOptions builder, convenience functions
python.rs — PyO3 Python bindings
types.rs — Shared types: TextItem, TextLine, PdfRect, ItemType
text_utils.rs — Character/text helpers (CJK, RTL, ligatures, bold/italic)
process_mode.rs — ProcessMode enum (DetectOnly, Analyze, Full)
detector.rs — Fast PDF type detection without full document load
glyph_names.rs — Adobe Glyph List → Unicode mapping
tounicode.rs — ToUnicode CMap parsing for CID-encoded text
extractor/ — Text extraction pipeline
tables/ — Table detection and formatting
markdown/ — Markdown conversion and structure detection
bin/ — CLI tools (pdf2md, detect_pdf)
napi/ — Node.js/Bun bindings (napi-rs)
wasm/ — Browser bindings (wasm-bindgen)
分类原理
- 解析 xref 表与页面树(不加载完整对象)
- 根据
ScanStrategy选择页面(默认:抽取 8 页样本) - 在内容流中查找
Tj/TJ(文本操作符)和Do(图像操作符) - 根据采样页面中是否存在文本操作符进行分类
可在毫秒内识别 300 多页的 PDF。结果包含 pages_needing_ocr——一个列出缺少文本的具体页码的列表,从而支持按页路由 OCR,而不是全有或全无。
扫描策略
| 策略 | 行为 | 适用场景 |
|---|---|---|
EarlyExit |
扫描所有页面,遇到第一个非文本页面即停止 | 适用于将文本型 PDF 路由到快速提取流程的管道 |
Full |
扫描所有页面,不提前退出 | 准确区分混合型与扫描型 PDF |
Sample(n)(默认:Sample(8)) |
均匀抽取 n 页(首页、末页、中间页) |
更重视速度而非精度的超大 PDF |
Pages(vec) |
仅扫描指定的从 1 开始的页码 | 调用方已知需要检查哪些页面时 |
Markdown 输出
转换器可处理:
| 元素 | 检测方式 |
|---|---|
| 标题(H1-H4) | 相对于正文文字的字号层级,并按 0.5pt 聚类 |
| 粗体/斜体 | 字体名称模式(Bold、Italic、Oblique) |
| 无序列表 | •、-、*、○、●、◦ 前缀 |
| 有序列表 | 1.、1)、(1) 模式 |
| 字母列表 | a.、a)、(a) 模式 |
| 代码块 | 等宽字体(Courier、Consolas、Monaco、Menlo、Fira Code、JetBrains Mono)及关键字检测 |
| 表格 | 基于 PDF 绘图操作的矩形检测 + 基于文本对齐的启发式检测 |
| 财务表格 | 针对合并数值的分词拆分 |
| 题注 | 检测 “Figure”、“Table”、“Source:” 前缀 |
| 下标/上标 | 相对于基线的字号与 Y 偏移 |
| URL | 转换为 Markdown 链接 |
| 断词连字符 | 重新合并跨行断开的单词 |
| 页码 | 从输出中过滤 |
| 首字放大 | 大号首字母与后续文本合并 |
| 点引导线 | 目录风格的点线压缩为 " ... " |
适用场景:智能 PDF 路由
pdf-inspector 专为大规模 PDF 处理流程而设计。无需将每一份 PDF 都送入 OCR:
PDF arrives
→ pdf-inspector classifies it (~20ms)
→ TextBased + high confidence?
YES → extract locally (~150ms), done
NO → send to OCR service (2-10s)
这对大多数已经是文本型 PDF 的文件(如报告、论文、发票、法律文件)可节省成本并降低延迟。
调试
关于 RUST_LOG 环境变量的用法,参见 docs/debugging.md。
许可
Introduction
用于 PDF 检查、分类和文本提取的快速 Rust 库。智能检测扫描型与文本型 PDF,助力实现智能路由决策。【此简介由AI生成】