DEBUG.WIKI
ZgoCloud:多地区部署,按需选节点;日本、美国、香港、德国
搬瓦工;先看线路,再选 VPS;CN2 GIA · 对应线路套餐;查看线路 →
V.PS:让项目靠近用户,亚太、欧洲、北美 KVM VPS

pypdf 读取书签报 NoneType.get_object,检查空 Outlines 引用

PDF 的 Outlines 指向空闲或缺失对象时,旧 pypdf 可能对 None 调用 get_object。正式 6.21.2 已有空引用保护;返回空书签不代表恢复了原来缺失的目录。

有些从 Google 文档或演示文稿导出的 PDF 可以读取页面,访问 reader.outline 时却报:

Object 5 0 not defined.
AttributeError: 'NoneType' object has no attribute 'get_object'

pypdf 6.17.0 到部分后续版本的一个失败入口,是文档目录的 /Outlines 指向了交叉引用表中的空闲或缺失对象。读取这个间接引用后得到 None,旧实现接着调用 .get_object(),最终把空引用变成了 Python 异常。

/Creator 显示 Google 只是文件来源线索,不能据此判定每份 Google PDF 都有问题。关键是堆栈停在书签解析,以及该文件的 /Outlines 引用实际无法解析。

用包含空引用保护的正式版本读取原件

当前正式 pypdf 6.21.2 的 _get_outline() 已在取得 /Outlines 后检查空值,并对非字典值作保护。空引用会返回当前空书签列表,而不是继续对 None 调用方法。这里确认的是 6.21.2 具备该保护,不据此确定首次修复版本。

按项目约束更新处理 PDF 的环境,保留原文件和旧依赖记录,然后用同一份输入重新读取:

from pypdf import PdfReader

reader = PdfReader("input.pdf")
outline = reader.outline
print("top-level outline entries:", len(outline))

将路径换成已获准处理的原始文件。这段只读取书签,不会修复或覆盖 PDF;打印的是顶层列表条目数,不是整棵嵌套书签树的总数。

缺失引用的文件返回空列表,不代表原来存在的书签已经被恢复。若业务必须保留目录结构,应找完整原件或重新导出,再检查书签标题和目标页。没有可解析对象时,校验器无法凭空重建其内容。

页面内容与书签分别验收

页面能够读取,并不能说明书签结构完整;反过来,空书签列表也不意味着页面正文为空。复查预期页数、关键页面内容,以及书签是否符合这份文件本来的用途。需要重新保存时使用新文件名,先保留输入原件。

不要通过全局捕获 AttributeError 再把任意书签失败都替换成 []。损坏的目标页、异常的目录链或其他代码中的空对象,可能有不同原因;宽泛吞掉异常会把“目录不可用”伪装成“文件本来没有目录”。

这项版本处理只针对已确认的 /Outlines 空闲或缺失间接引用。若更新后故障转到其他解析步骤,保留新的完整错误继续定位,不修改安装包中的私有 _objects 数组,也不为了绕过一份文件的问题降低所有输入的检查要求。