阅读文本 / Reading text
本文使用合成样本演示处理方法。代码已通过隔离环境中的示例检查;这不代表对所有真实文件或产品效果的保证。处理重要文件前,请保留原件,并按文中的边界与验收项复核。
这篇先解决哪一个问题
书签层级必须先检查再写入。第一项为一级,后续最多比前一项增加一级;示例拒绝非法层级和越界页码,不自动改层级伪造目录结构。书签页码从一开始,页面索引通常从零开始。
自包含的合成示例
依赖见导入列表。代码在内存中构造输入;运行记录单独提供,不代表对所有真实文件的保证。
import pymupdf
def validate(rows, pages):
previous = 0
for level, title, page in rows:
if type(level) is not int or level < 1 or level > previous + 1:
raise ValueError("invalid hierarchy")
if type(page) is not int or not 1 <= page <= pages:
raise ValueError("invalid destination")
if not isinstance(title, str) or not title.strip():
raise ValueError("empty title")
previous = level
return rows
with pymupdf.open() as doc:
for _ in range(3):
doc.new_page()
rows = [[1, "Chapter", 1], [2, "Section", 2], [1, "Appendix", 3]]
doc.set_toc(validate(rows, doc.page_count))
assert doc.get_toc() == rows
assert len(doc.get_toc()) == 3
for bad in [[[2, "Bad", 1]], [[1, "Bad", 99]], [[1, "", 1]]]:
try:
validate(bad, doc.page_count)
except ValueError:
pass
else:
raise AssertionError("invalid outline accepted")
PDF 目录页能点,抽取后却丢了层级怎么办
在PDF阅读器中点击目录跳转正常,但使用脚本提取后却发现层级扁平化、页码错位甚至抛出索引异常。这通常并非文件损坏,而是
get_toc()
返回的原始列表未经结构化校验所致。该方法默认输出
[level, title, page]
三元组列表,其中
page
是1-based物理页码,而
level
仅表示嵌套深度,不保证连续或合法。若源PDF由扫描合并工具生成,常出现层级跳跃(如从1直接到3)、页码为0或超出总页数、标题含控制字符等问题。直接用于下游任务会导致翻译分段错乱或链接失效。更隐蔽的问题是,某些PDF虽然视觉上有目录页,但并未嵌入书签元数据,此时
get_toc()
返回空列表属正常现象,需改用文本布局分析而非盲目重试。
合成示例中的正确与错误输入处理
以下合成示例展示典型边界情况。正确输入应为层级连续、页码在
[1, doc.page_count]
范围内的三元组列表。例如
[[1, "引言", 1], [2, "背景", 2], [1, "方法", 5]]
是合法的,尽管第二级出现在第一级之后,但符合PDF大纲语法。错误输入包括:层级为0或负数、页码为0、页码超过总页数、标题为空字符串或仅含空白符。处理方式应为:跳过页码无效项并记录警告;将层级<1的项强制设为1;对空标题保留占位符如
[untitled]
以维持结构完整性;不因单个错误中断整个TOC解析。注意,这些规则是为保障下游流程鲁棒性而设,并非PDF标准强制要求。实测发现,当页码越界时PyMuPDF会打印警告但不抛异常,因此校验函数必须主动过滤而非依赖库行为。
验收标准与人工审查边界
观察现象
处理决定
是否适用自动化
页码=0 或 >总页数
丢弃该条目,记录日志
是
层级<1 或非整数
强制设为1
是
标题全空白或纯符号
替换为[untitled]
是
层级跳跃(如1→3)
保留原始层级,不补中间层
是(结构合法)
同一标题对应多个不同页码
标记为歧义,转人工
否
TOC条目数>200且无层级变化
怀疑OCR误识别,需人工核对
否
包含外部URI或JavaScript动作
过滤非页面跳转项
是(安全策略)
EPUB等重排文档页码为(chapter,pno)
不适用本页码校验逻辑
否(需专用处理)
注意:此表仅针对PDF目录元数据提取环节。若PDF本身无书签但视觉上有目录页,则
get_toc()
返回空列表属正常现象,此时需改用文本布局分析,不属于本节范围。代码演示仅校验结构合法性,端到端效果还需结合渲染验证跳转准确性。
参考资料与下一步
PyMuPDF Document.get_toc 官方文档: https://pymupdf.readthedocs.io/en/latest/document.html#Document.get_toc
建议下一步:准备一份含已知目录问题的测试PDF,运行上述校验脚本,统计各类异常占比;若高频出现层级跳跃或页码偏移,考虑在翻译前增加TOC重建步骤。
将这份检查清单用于文档翻译
先把页面顺序、来源位置与文本完整性检查清楚,再把同一份脱敏样本交给翻译流程。译后仍要检查标题、正文和图注是否正确对应,不能只看文字是否通顺。
OmniDoc(产品入口)
提供多格式文档翻译入口,官网介绍了 OCR、术语表与双语对照功能。对希望直接从文件开始处理的团队,这是一条值得用实际样本评估的路径。请使用有权上传的脱敏文件,并用本篇的检查项复核结果;这里不声称 OmniDoc 使用了本文的开源库或内部算法,也不以示例代替产品性能测试。
- 1 -
更新于 2026-10-08