阅读文本 / Reading text
本文使用合成样本演示处理方法。代码已通过隔离环境中的示例检查;这不代表对所有真实文件或产品效果的保证。处理重要文件前,请保留原件,并按文中的边界与验收项复核。
“同一段代码在我电脑上能跑”不是一份复现报告。PDF 渲染与文档转换还受库版本、系统字体、OCR 语言包和外部组件影响。把这些信息收集完整,才能判断差异来自输入、代码还是环境。
分开记录 Python 包与系统资源
importlib.metadata
可以读取已安装发行包版本,但看不到所有字体、系统动态库或外部 OCR 数据文件。不要把一张
pip freeze
清单称为完整环境。包的发行名与导入名也可能不同,例如导入
PIL
对应的发行包是
Pillow
。
一个不会因缺包而崩溃的报告器
import json
import platform
from importlib import metadata
def package_version(name):
try:
return metadata.version(name)
except metadata.PackageNotFoundError:
return "not-installed"
def report(names):
return {"python": platform.python_version(),
"system": platform.system(),
"packages": {name: package_version(name) for name in names},
"fonts_manifest": "not-collected",
"ocr_language_data": "not-collected"}
data = report(["PyMuPDF", "Pillow", "omnidoc-synthetic-missing-package"])
assert data["packages"]["omnidoc-synthetic-missing-package"] == "not-installed"
assert data["python"]
assert data["fonts_manifest"] == "not-collected"
assert json.loads(json.dumps(data)) == data
代码只读取当前环境,不安装依赖,也不联网。结果中的未收集项目应保持明确标记,不能自动填成“默认字体”或“最新版”。报告可以另外关联容器镜像摘要、锁文件和输入文件摘要,但不要导出认证配置或全部环境变量。
比较时先找最有区分度的信息
差异
常见影响方向
后续验证
字体缺失
替代字体与排版改变
比对字体清单和渲染样本
OCR 语言包不同
识别路径改变
用相同语言数据复测
PDF 库版本不同
接口或解析行为变化
查版本说明并跑最小样本
输入摘要不同
根本不是同一文件
先统一输入再讨论环境
环境相同不保证所有输出逐字节相同
时间戳、随机 ID 和压缩元数据也可能造成产物哈希变化。需要区分“字节级可复现”和“内容及版式满足同一验收标准”。先确定需要哪种保证,再选比较方法,避免用错指标。
让文档翻译问题更容易沟通
当本地预处理结果与
OmniDoc(产品入口)
工作流出现差异,可以附上脱敏样本、处理阶段和环境报告。这样的反馈比一句“格式乱了”更容易定位,也便于判断是否需要更新依赖、补字体或调整输入准备。
参考:
Python importlib.metadata
。
- 1 -
更新于 2026-10-08