我的知识记录

Python PDF按书签批量拆分 章节拆分教程

用Python读取PDF书签目录,自动按一级章节把整本PDF拆成多个小PDF,每个章节一个文件,保留文件名。

场景痛点

一本几百页的PDF电子书或规范,自带书签目录,想按章节拆成独立小文件发给不同人看。手动记下每个书签对应的页码区间,再一段段拆分,繁琐又容易错。用Python脚本读取书签树,自动计算每章的起止页码,一次性拆出几十个章节PDF。

用到的库

pip install PyPDF2

完整代码

# -*- coding: utf-8 -*-
"""
按 PDF 书签(一级大纲)自动拆分 PDF
"""
import os
import re
from PyPDF2 import PdfReader, PdfWriter


def _collect_top_level_bookmarks(outlines, reader):
"""
只取一级书签,返回 [(标题, 起始页码1基), ...]
"""
result = []
for item in outlines:
# 一级书签本身不是 list;它下面的子书签才是 list
if isinstance(item, list):
continue
title = item.title
start_page = reader.get_destination_page_number(item) + 1  # 转1基
result.append((title, start_page))
return result


def split_by_bookmarks(pdf_path: str, out_dir: str = "./chapters") -> None:
os.makedirs(out_dir, exist_ok=True)
reader = PdfReader(pdf_path)
total_pages = len(reader.pages)

bookmarks = _collect_top_level_bookmarks(reader.outline, reader)
print(f"共 {len(bookmarks)} 个一级书签")

# 计算每章的结束页 = 下一章起始页 - 1;最后一章结束 = total_pages
for i, (title, start) in enumerate(bookmarks):
end = bookmarks[i + 1][1] - 1 if i + 1 < len(bookmarks) else total_pages
if start > end:
continue

writer = PdfWriter()
for pno in range(start - 1, end):  # 0基索引
writer.add_page(reader.pages[pno])

# 清洗文件名中的非法字符
safe_title = re.sub(r'[\\/:*?"<>|]', "_", title).strip()
out_path = os.path.join(out_dir, f"{i+1:02d}_{safe_title}.pdf")
with open(out_path, "wb") as f:
writer.write(f)
print(f"[{i+1}] {title} -> 第{start}-{end}页")


if __name__ == "__main__":
split_by_bookmarks("book.pdf")

代码讲解

  • _collect_top_level_bookmarks 只挑一级书签(跳过嵌套 list),记录每章起始页码。
  • 关键算法:第 i 章的结束页 = 第 i+1 章起始页 - 1;最后一章结束页 = 总页数。
  • 然后按页码区间循环 add_page,写出每个章节PDF。
  • 文件名用 re.sub 去掉 Windows 非法字符 \ / : * ? " < > |,避免写盘报错。
  • 序号 :02d 补零,保证文件管理器按文件名排序后章节顺序正确。

运行结果

./chapters/ 目录下生成 01_封面.pdf02_第一章 项目背景.pdf03_第二章 技术方案.pdf……每个文件正好对应该书签到下一书签之间的页面。

注意事项

  • 只按一级书签拆;二级、三级书签会被忽略。想按所有层级拆,需要递归处理并保留子目录。
  • 如果PDF没有书签,本脚本不适用,需要先按章节关键词做文本定位。
  • 有的书签指向页面中间而非页面开头,拆出来的章节会从那一页开始,符合书签原意。
  • 跨章的图、表不会被复制到新文件,只复制页面。

Python PDF按书签批量拆分 章节拆分教程

标签:

更新时间:2026-09-14 21:32:25

上一篇:Python拆分PDF按页码 一页一个文件方法

下一篇:Python扫描件批量生成PDF:按文件名排序合并