pdf-inspector 错误处理与限制 - 排查指南
错误处理限制
先明确一点:pdf-inspector 的哲学是不假装成功——提不出的内容它会明确告诉你哪一页、为什么、该怎么办。这篇把常见异常情况和已知限制一次讲清。
异常情况,一张表
| 情况 | 表现 | 处理思路 |
|---|---|---|
| 文档是扫描型/图片型 | pdfType = Scanned/ImageBased,markdown 为空或缺失 | 需要 OCR:原生版启用选择性 OCR,或路由到外部 OCR 服务 |
| 部分页需要 OCR | pagesNeedingOcr 列出页码(Mixed 常见) | 只把这些页送 OCR,其余照常本地提取 |
| 字体编码损坏 | Python has_encoding_issues=True;区域提取 needsOcr=True(ocrReason="suspected_garbled_text") | 这些页回退 OCR;这是源文件的问题,重试无用 |
| PDF 加密 | 解析报错 | 先解密 / 移除密码保护 |
| PDF 损坏 | 解析报错 | 用原软件重新导出一份再试 |
| 浏览器端解析失败 | WASM 抛异常 | 确认是合法 PDF 且未加密;超大文件留意内存 |
已知限制(重要)
浏览器 WASM 版不含 OCR
纯图片/扫描件在浏览器端只会得到类型判定和明确提示。这是设计边界——OCR 运行时(PDFium + ONNX Runtime + 模型)体积和形态都不适合塞进网页。
替代方案:
- 服务端用原生包的选择性 OCR(
processPdfWithOcr/process_pdf_with_ocr) - 或先用外部 OCR 把文本层补上,再用 WASM 版提取
视觉细节不保留
输出是 Markdown 不是 PDF 快照。复杂排版(文本框绝对定位、艺术字、精密图表)会降级为可读文本——信息完整靠基准测试的 0.875 分保证,但不保证像素级还原。
页码索引跨语言不完全一致
Python 的 pages_needing_ocr 是 1-indexed,而 extract_pages_markdown 结果里的 page 是 0-indexed;Node 的 pagesNeedingOcr 是 0-indexed 而 processPdfWithOcr 的 pageNumbers 是 1-indexed。写路由逻辑时以各端官方文档为准,别想当然。
同步 API 会占住调用线程
Node 端的 processPdf / classifyPdf 是同步的,直接跑在事件循环上。服务端一律用 *Async 变体(libuv 线程池);浏览器端大文件放 Web Worker。
高频问题
转出来是空的?
先看类型判定结果:大概率文档不是 TextBased。用 detect-pdf document.pdf --analyze --json 确认;如果判定是文本型但输出为空,检查是否加密,并换官方工具确认文件本身可读。
提取出来是乱码?
九成是源文件的字体编码就是坏的(GID 编码、缺失 ToUnicode CMap)。pdf-inspector 已经把这些页标记出来了(has_encoding_issues / needsOcr),正确做法是让这些页走 OCR 兜底,而不是反复重试。
多栏排版的顺序不对?
pdf-inspector 的阅读顺序在基准里拿 0.915 分(第一),但对极端版面(复杂表格嵌套分栏、艺术排版)仍可能判断失误。遇到时可以对比逐页模式(extractPagesMarkdown)的输出定位问题页面。
解析很慢?
正常文本型 PDF 全流程 200ms 以内。如果很慢:大文件把分类抽样调低(Rust ScanStrategy::Sample(n));只需要部分内容时传 pages 参数;WASM 场景记得只 init() 一次。
怎么确认没转错?
抽查三样:标题层级(# 数量)、多栏顺序、表格规整度。批量入库建议对关键文档做一次快照对比。
一句话
先判定、再提取、编码坏了走 OCR——记住这条决策链,pdf-inspector 的坑基本就踩不完了。