正在打开仓库文档
正在打开仓库文档
它把 PDF 的检查、分类和文本提取放到一个快速库里,体现了 AI 数据入口应先做路由判断。
中文阅读版只翻译说明性文字;术语、代码、命令、链接与原有 Markdown 结构保持不变。
用于 PDF 分类与文本提取的高速 Rust 库。默认情况下,它会检测 PDF 是文本型还是扫描型,以位置感知的方式提取文本,并转换为干净的 Markdown,全程不使用 OCR。原生 Rust 和 CLI 使用者可以选择启用选择性 OCR。包含 Python、Node.js 和 browser WebAssembly 的绑定。
由 Firecrawl 构建,可在 200ms 内于本地处理文本型 PDF,为约 54% 不需要 OCR 的 PDF 省去昂贵的 OCR 服务。
rotation 角度,而不是坍缩为零宽度。在 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。速度是在排除一次预热运行后,五次交替或轮换完整语料库运行的中位数,每个解析器在单进程中按顺序处理文档。
完整的解析器配置、逐文档预测结果、评估器输出以及生成的图表可在 reproducible results branch 中获取。
最适用场景: 重视速度、阅读顺序和表格结构的原生文本 PDF。在本对比中,pdf-inspector 在总体、阅读顺序和表格得分上领先,并拥有最快的完整运行速度。这使它成为报告、研究论文、财务文档、发票以及需要干净、结构化 Markdown 而不引入 OCR 延迟或基础设施的法务 PDF 的可靠本地默认选择。
使用 paired benchmark harness 在完全相同的语料库和评估器版本上对比两个本地构建。
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
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
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
从 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
# 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 runtime setup guide。更底层的控制请参阅 Rust API guide。
如果是从源码检出的仓库运行,请改用 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)
ScanStrategy 选择页面(默认:采样 8 页)Tj/TJ(文本操作符)和 Do(图像操作符)它能在毫秒级检测 300 多页的 PDF。结果包含 pages_needing_ocr —— 一个缺少文本的具体页码列表,从而支持逐页 OCR 路由,而非全有或全无。
| 策略 | 行为 | 最适合 |
|---|---|---|
EarlyExit | 扫描所有页面,遇到第一个非文本页面即停止 | 将 TextBased PDF 路由到快速提取的管道 |
Full | 扫描所有页面,不提前退出 | 精确区分 Mixed 与 Scanned |
Sample(n)(默认为 Sample(8)) | 采样 n 个均匀分布的页面(首页、末页、中间页) | 速度比精度更重要的超大 PDF |
Pages(vec) | 只扫描指定的 1 起始页码 | 调用方明确知道要检查哪些页面时 |
转换器可处理:
| 元素 | 检测方式 |
|---|---|
| 标题(H1-H4) | 相对于正文字号的字号分层,以 0.5pt 聚类 |
| 粗体/斜体 | 字体名称模式(Bold, Italic, Oblique) |
| 无序列表 | •, -, *, ○, ●, ◦ 前缀 |
| 有序列表 | 1., 1), (1) 模式 |
| 字母列表 | a., a), (a) 模式 |
| 代码块 | 等宽字体(Courier, Consolas, Monaco, Menlo, Fira Code, JetBrains Mono)及关键字检测 |
| 表格 | 基于 PDF 绘图操作的矩形检测 + 基于文本对齐的启发式检测 |
| 财务表格 | 对合并数值进行 Token 拆分 |
| 题注 | "Figure"、"Table"、"Source:" 前缀检测 |
| 下标/上标 | 相对基线的字号与 Y 偏移 |
| URLs | 转换为 Markdown 链接 |
| 断词连字符 | 重新拼接跨行断开的单词 |
| 页码 | 从输出中过滤掉 |
| 首字下沉 | 大号首字母与后续文本合并 |
| 前导点 | 目录式圆点折叠为 " ... " |
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。