Python提取PDF书签结构时遇ValueError报错求助
PDF书签提取报错:ValueError: not enough values to unpack 解决方案
问题说明
尝试提取PDF的书签层级结构,参考Stack Overflow代码实现后,代码可运行但频繁触发ValueError,报错提示为not enough values to unpack (expected 3, got 1)或not enough values to unpack (expected 3, got 2)。
报错堆栈
C:\Users\XXXXX\PycharmProjects\pythonProject\venv\Scripts\python.exe "C:\Google Drive\python\projects\Get bookmarks.py" Traceback (most recent call last): File "C:\Google Drive\python\projects\Get bookmarks.py", line 24, in bms = bookmark_dict(reader.outline, use_labels=False) File "C:\Users\XXXXX\PycharmProjects\pythonProject\venv\lib\site-packages\pypdf_reader.py", line 844, in outline return self._get_outline() File "C:\Users\XXXXX\PycharmProjects\pythonProject\venv\lib\site-packages\pypdf_reader.py", line 880, in _get_outline outline_obj = self._build_outline_item(node) File "C:\Users\XXXXX\PycharmProjects\pythonProject\venv\lib\site-packages\pypdf_reader.py", line 1054, in _build_outline_item outline_item = self._build_destination(title, dest) File "C:\Users\XXXXX\PycharmProjects\pythonProject\venv\lib\site-packages\pypdf_reader.py", line 1018, in _build_destination return Destination(title, page, Fit(fit_type=typ, fit_args=array)) # type: ignore File "C:\Users\XXXXX\PycharmProjects\pythonProject\venv\lib\site-packages\pypdf\generic_data_structures.py", line 1495, in __init__ ( ValueError: not enough values to unpack (expected 3, got 2) Process finished with exit code 1
原使用代码
from typing import Dict, Union from pypdf import PdfReader def bookmark_dict( bookmark_list, use_labels: bool = False ) -> Dict[Union[str, int], str]: result = {} for item in bookmark_list: if isinstance(item, list): result.update(bookmark_dict(item)) else: page_index = reader.get_destination_page_number(item) page_label = reader.page_labels[page_index] if use_labels: result[page_label] = item.title else: result[page_index] = item.title return result if __name__ == "__main__": folder ="x:\\" file="TestPDF.pdf" reader = PdfReader(folder + file) bms = bookmark_dict(reader.outline, use_labels=False) for page_nb, title in sorted(bms.items(), key=lambda n: f"{str(n[0]):>5}"): print(f"{page_nb:>3}: {title}")
解决方案
这个报错是pypdf库解析部分特殊PDF的目标定位(Destination)时的兼容性问题,部分PDF的Fit参数格式不符合库的预期。可通过以下两种方式解决:
1. 升级pypdf到最新版本
新版本修复了更多PDF兼容性问题,执行命令:
pip install --upgrade pypdf
2. 异常捕获+保留层级结构的优化代码
如果升级后仍有问题,可修改代码捕获解析异常,跳过无效书签同时保留层级关系:
from typing import Dict, List from pypdf import PdfReader from pypdf.errors import PdfReadError def extract_bookmarks(bookmark_list, depth: int = 0) -> List[Dict]: """提取带层级的PDF书签""" result = [] for item in bookmark_list: if isinstance(item, list): # 递归处理子层级书签 result.extend(extract_bookmarks(item, depth + 1)) else: try: page_index = reader.get_destination_page_number(item) page_label = reader.page_labels[page_index] result.append({ "title": item.title, "page_index": page_index, "page_label": page_label, "depth": depth }) except (ValueError, PdfReadError): # 跳过解析失败的书签项 print(f"跳过无法解析的书签: {item.title}") return result if __name__ == "__main__": folder = "x:\\" file = "TestPDF.pdf" reader = PdfReader(folder + file) bookmarks = extract_bookmarks(reader.outline) # 打印带层级缩进的书签 for bm in bookmarks: indent = " " * bm["depth"] print(f"{bm['page_index']:>3}: {indent}{bm['title']}")
优化点说明:
- 新增层级参数
depth,通过缩进展示书签层级 - 捕获
ValueError和PdfReadError异常,避免程序崩溃 - 输出结构更清晰,保留原书签的层级关系
内容的提问来源于stack exchange,提问作者Paulo Alves
相关产品推荐
相关产品推荐

