
本文介绍两种可靠方法提取 pdf 中的章节标题:一是直接解析内置书签(目录结构),适用于标准 pdf;二是基于文本字体大小与位置特征进行智能识别,适用于无书签的扫描或排版复杂文档。
本文介绍两种可靠方法提取 pdf 中的章节标题:一是直接解析内置书签(目录结构),适用于标准 pdf;二是基于文本字体大小与位置特征进行智能识别,适用于无书签的扫描或排版复杂文档。
PDF 文档中的章节标题(如“第1章 引言”“3.2 实验设计”)通常有两种存在形式:一种是逻辑结构化的书签(Bookmarks),即 PDF 内置的可交互目录;另一种是视觉呈现的标题文本,依赖字体、字号、居中/加粗等排版特征。二者需采用不同策略提取。
✅ 方案一:优先提取内置书签(推荐,准确率高)
大多数由 Word、LaTeX 或专业排版工具生成的 PDF 都会嵌入结构化书签。使用 PyPDF2(v3.0+)或 pypdf 可直接读取:
from pypdf import PdfReader
reader = PdfReader("document.pdf")
bookmarks = reader.outline # 返回嵌套的 Bookmark 对象列表
def extract_titles(bookmark_list, titles=None):
if titles is None:
titles = []
for item in bookmark_list:
if isinstance(item, list): # 子层级
extract_titles(item, titles)
else:
titles.append(item.title.strip())
return titles
chapter_titles = extract_titles(bookmarks)
print(chapter_titles)
# 输出示例:['摘要', '1 绪论', '2 相关工作', '3 方法设计', '参考文献']
⚠️ 注意:若 reader.outline 返回空列表,说明该 PDF 未嵌入书签(常见于扫描件或导出设置关闭了“生成书签”的选项)。
✅ 方案二:基于文本特征的智能识别(适用于无书签 PDF)
当书签不可用时,需借助底层文本分析工具——pdfminer.six(推荐替代已停更的 pdfminer)。它能精确获取每段文本的坐标、字体名、字号、颜色等元信息:
pip install pdfminer.six
from pdfminer.high_level import extract_pages
from pdfminer.layout import LTTextContainer, LTChar
def detect_section_titles(pdf_path, min_font_size=16, top_margin_ratio=0.1):
titles = []
for page_num, page_layout in enumerate(extract_pages(pdf_path)):
page_height = page_layout.height
for element in page_layout:
if isinstance(element, LTTextContainer):
# 获取该文本块中所有字符的平均字号
font_sizes = []
for text_obj in element:
if hasattr(text_obj, 'get_text') and hasattr(text_obj, '_objs'):
for char in text_obj._objs:
if isinstance(char, LTChar):
font_sizes.append(char.size)
if not font_sizes:
continue
avg_size = sum(font_sizes) / len(font_sizes)
# 判断是否为页首大字号文本(典型标题特征)
if (avg_size >= min_font_size and
element.y1 > page_height * (1 - top_margin_ratio)): # y1 是顶部坐标
text = element.get_text().strip()
if len(text) > 3 and not text.isdigit(): # 过滤纯数字页码或过短文本
titles.append((page_num + 1, text))
return titles
# 使用示例
titles = detect_section_titles("report.pdf")
for page, title in titles:
print(f"[P{page}] {title}")
? 关键优化点说明:
- 不仅依赖“首行”,而是结合 垂直位置(靠近页顶)+ 字号显著大于正文 + 文本长度合理 三重判断;
- 推荐先用 pdfminer 的 pdf2txt.py 命令行工具调试:pdf2txt.py -t xml document.pdf > debug.xml,可视化查看布局与字体属性;
- 对扫描 PDF,需先 OCR(如 pytesseract + pdf2image),再对识别结果做类似分析。
总结建议
| 场景 | 推荐方案 | 工具 | 准确性 |
|---|---|---|---|
| 含结构化书签的 PDF(主流出版物、学术论文) | 解析 reader.outline | pypdf | ★★★★★ |
| 无书签但排版规范的 PDF(企业报告、教材) | 字体+位置规则匹配 | pdfminer.six | ★★★★☆ |
| 扫描件或图像型 PDF | OCR + 规则/模型识别 | pytesseract + 自定义逻辑 | ★★☆☆☆(需调优) |
实际项目中,建议优先尝试书签提取;失败后再启用 pdfminer 特征分析,并根据目标文档反复调整 min_font_size 和 top_margin_ratio 等阈值。两者结合,可覆盖绝大多数 PDF 标题提取需求。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











