You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 20:40:27