记录一下那天晚上的排查过程。供应商给的 400 份 PDF 合同,用 pdfplumber 抽文本全是乱码,字符显示为 䏿–‡ 这类形式,人工看页面却完全正常,下游抽取管线全部失败。
刚开始盯着「文本层是旧版扫描件叠加的伪文本」,折腾了半个多小时,排掉了。
把日志和配置对完,能解释这个现象的基本就这几处。PDF 用了非嵌入字体,缺少 ToUnicode 映射。也可能是文档被工具二次生成,编码信息丢失。
少数情况下是抽取库按字节解码而不是按 CMap 解析。
先确认页面是否有可用文本层
python -c "import pdfplumber;pdf=pdfplumber.open('a.pdf');print(repr(pdf.pages[0].extract_text()[:40]))"
然后检查字体是否带 ToUnicode 表
python -c "import fitz;d=fitz.open('a.pdf');print([f[3] for f in d[0].get_fonts()])"
文本层不可信时直接渲染成图走 OCR
python -c "import fitz;d=fitz.open('a.pdf');[p.get_pixmap(dpi=300).save('p%d.png'%i) for i,p in enumerate(d)]"
剩下的就是用 OCR 结果与页面截图抽检比对
python ocr_check.py --pdf a.pdf --dpi 300 --sample 3
改完先别撤,确认这几项。渲染后走 OCR 的 400 份合同抽取字段完整,金额与甲乙方名称抽检 30 份全部正确,乱码字符不再进入下游。
这里还有个坑。PDF 乱码多半是字体映射缺失而不是编码问题,修字库成本高于直接渲染成图走 OCR,批量场景优先选后者。监控比日志更早给出信号,事后回看经常能提前半小时发现异常。
