先给结论:扫描件读不出内容不是失败,是它本来就没有可读的文字。PDF里的文字有两种存在形式——文本层(可抽取的字符)和图像(像素)。扫描件只有后者。
实测两份文件,区别一眼可见:
| 文件 | 页数 | 可抽取字符数 | 内嵌图片数 | 能读出正文吗 |
|---|---|---|---|---|
| 有文本层的PDF | 1 | 34 | 0 | 能 |
| 同一页渲染成图再包成PDF | 1 | 0 | 1 | 不能 |
检测方法(不依赖任何模型):
import pymupdf d = pymupdf.open(path) txt = "".join(p.get_text() for p in d) print(len(txt.strip()), "字符", sum(len(p.get_images(full=True)) for p in d), "张图")
字符数为0而图片数大于0,就是扫描件。这个判断可以在把文件交给模型之前做完,省一整轮。
为什么这件事必须先查
模型拿到一份没有文本层的PDF,只有三种可能:说读不出、编一段看起来合理的内容、或者转去用OCR(如果工具链里有)。第三种最好,前两种都是你要花时间分辨的坏结果。
所以配方的正确写法是:先列出无文本层的文件,单独说明,不要静默跳过,也不要让它猜。这比事后核对产物省事得多。
怎么办
- 批量跑一遍字符数检测,把0字符的挑出来单独列一节。
- 有OCR就过一遍OCR;没有就在产物里标「读取失败·无文本层」,保留文件名与页数。
- 在给模型的指令里明确写:读不到正文的标「读取失败」,不要根据文件名推测内容。