Node.js 中使用 pdf-inspector - @firecrawl/pdf-inspector 教程
API 参考Node.js
pdf-inspector 的 Node.js 绑定叫 @firecrawl/pdf-inspector,基于 napi-rs 的原生实现。同步 API 直接在调用线程执行;异步 API 跑在 libuv 线程池里,不阻塞事件循环——高并发服务里批量解析也不会卡住主线程。
安装
npm install @firecrawl/pdf-inspector
# 或
bun add @firecrawl/pdf-inspector预构建二进制覆盖 Linux x64/ARM64(glibc 与 musl)、macOS ARM64、Windows x64——npm 只装匹配你平台的那个,无需 Rust 工具链。包内置 TypeScript 类型。
核心 API
import { classifyPdf, processPdf, extractPagesMarkdown } from '@firecrawl/pdf-inspector'
// 1. 轻量分类(~10–50ms)
const c = classifyPdf(pdf)
// { pdfType: 'TextBased', pageCount: 42,
// pagesNeedingOcr: [5, 12], confidence: 0.875 }
// 2. 一步到位:检测 + 提取 + Markdown(同步)
const result = processPdf(pdf)
console.log(result.markdown)
// 3. 逐页 Markdown(带 needsOcr 等版面元数据)
const { pages } = extractPagesMarkdown(pdf)
for (const p of pages) {
console.log(p.page, p.needsOcr)
}其他可用函数:detectPdf(只判定不提取)、extractText(纯文本)、extractTextInRegions(按包围盒提取,区域级 needsOcr 标记)。
同步还是异步?
import { classifyPdfAsync, extractPagesMarkdownAsync } from '@firecrawl/pdf-inspector'
// 脚本里跑一次:同步版没问题
const classification = classifyPdf(pdf)
// 服务端 / 大文件:用 Async 版本,libuv 线程池执行
const classification = await classifyPdfAsync(pdf)
if (classification.pdfType === 'TextBased') {
const { pages } = await extractPagesMarkdownAsync(pdf)
}异步版本在调用返回前就拷贝了输入 Buffer,之后复用或修改都安全。
选择性 OCR
import { OcrMode, processPdfWithOcr } from '@firecrawl/pdf-inspector'
const result = await processPdfWithOcr(pdf, {
mode: OcrMode.Auto, // 只 OCR 原生提取质量不过关的页面
pageNumbers: [1, 3], // 1-indexed
})
for (const page of result.pages) {
console.log(page.pageNumber, page.provenance.source) // native | ocr | fused
}
console.log(result.pagesRoutedToOcr)OCR 需要 PDFium 与 ONNX Runtime 共享库(环境变量 PDFIUM_LIB_PATH、ORT_DYLIB_PATH),模型集首次路由时才下载并做校验和验证;离线部署传 offline: true + 预热缓存或指定 modelDirectory。默认构建不含这些外部组件——不用 OCR 就永远不会加载它们。
常见场景
先分类再路由的批量入库
import { readdir, readFile, writeFile } from 'node:fs/promises'
import { classifyPdfAsync, extractPagesMarkdownAsync } from '@firecrawl/pdf-inspector'
const dir = './pdfs'
for (const name of await readdir(dir)) {
if (/\.pdf$/i.test(name)) {
const buf = await readFile(`${dir}/${name}`)
const c = await classifyPdfAsync(buf)
if (c.pdfType !== 'TextBased') {
console.warn(`跳过 ${name}:${c.pdfType},需 OCR 页 ${c.pagesNeedingOcr}`)
continue
}
const { pages } = await extractPagesMarkdownAsync(buf)
await writeFile(`${dir}/${name}.md`, pages.map(p => p.markdown).join('\n\n'))
}
}上传即解析
// 收到上传的 File 对象后直接解析字节
const bytes = new Uint8Array(await file.arrayBuffer())
const result = processPdf(bytes)
// 回给前端或继续喂给 LLM 都行喂给 AI Agent
把 processPdf 包装成工具函数暴露给 LLM 工具调用,Agent 就能「读懂」上传的 PDF:
const parsePdf = async (path) => (await import('@firecrawl/pdf-inspector')).processPdf(await readFile(path))
// 注册为 tool → Agent 直接调用小提示
- 服务端一律用
*Async变体;一次性脚本用同步版更省事 - 只要类型判定就别调
processPdf——classifyPdf快一个数量级 - 版本以官方 napi/README 为准