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

如何用Python获取PDF多页目录(TOC)页码范围并优化识别逻辑?

问题说明

已实现PDF单页目录(TOC)起始页码的获取,但无法处理多页目录场景。当前通过硬编码正则匹配TABLE OF CONTENTS识别目录页,需优化识别方法,并实现多页目录起止页码的获取(如页码3至7)。

现有代码

目录页识别函数

def get_toc_page(page_text, pg_no):   
    REG= "TABLE OF CONTENTS"
    if re.search(REG, page_text, re.IGNORECASE):
        search = re.search(REG, page_text, re.IGNORECASE)
        return REG, pg_no
    # else:
    #     return 'not found',pg_no

主处理逻辑

filelist = glob.glob(path)

for doc_path in tqdm(filelist):
  
    file_name = os.path.basename(doc_path)
  
    # 打开PDF
    doc = fitz.open(doc_path) 

    #print(file_name, ' : ', len(doc)) # 文档总页数

    i = -1  
    # 遍历页面
    for page in doc:
        i +=1
        if i == 10: # 仅检查前10页
            break

        try:
            page.wrap_contents()
            page_text = page.get_text("text")
            if get_toc_page(page_text, i) != None:
                print(file_name, get_toc_page(page_text, i))
        except Exception as e:
            print(e)
            print('处理出错:', file_name)                                          
解决方案

一、优化目录页识别方法

  1. 扩展关键词匹配:覆盖中英文常见的目录表述,避免单一关键词的局限性
    正则表达式改为:r"(TABLE OF CONTENTS|CONTENTS|目录|目錄)",忽略大小写匹配。
  2. 结合目录结构特征判断:目录页通常包含大量「标题+分隔符+页码」的格式(如1.1 引言........5),通过匹配这类结构辅助验证,减少误判。

二、多页目录起止页码获取逻辑

  1. 标记起始页:识别到目录起始页后,记录起始页码。
  2. 向后遍历验证后续页面:对后续页面,检查是否仍存在目录结构特征;若连续多页无目录特征,或出现正文起始标识(如第一章、Chapter 1),则标记为目录结束页。
  3. 设置合理的终止阈值:比如最多连续检查15页目录,避免无限遍历。

修改后的完整代码

import re
import glob
import os
from tqdm import tqdm
import fitz

def is_toc_page(page_text):
    # 匹配常见的目录关键词
    toc_keywords = r"(TABLE OF CONTENTS|CONTENTS|目录|目錄)"
    if re.search(toc_keywords, page_text, re.IGNORECASE):
        return True
    
    # 匹配目录特有的标题-页码结构(如 "章节名........123" 或 "章节名   123")
    toc_pattern = r".+[\. ]+\d+$"
    matches = re.findall(toc_pattern, page_text, re.MULTILINE)
    # 如果页面中这类结构超过3条,判定为目录页
    if len(matches) >= 3:
        return True
    
    return False

def get_toc_range(doc, max_check_pages=15):
    toc_start = None
    toc_end = None
    # 遍历前max_check_pages页查找目录
    for pg_no in range(min(max_check_pages, len(doc))):
        page = doc[pg_no]
        page_text = page.get_text("text")
        
        if is_toc_page(page_text):
            if toc_start is None:
                toc_start = pg_no
            # 更新当前目录结束页
            toc_end = pg_no
        else:
            # 如果已经识别过目录起始页,且当前页不是目录页,终止遍历
            if toc_start is not None:
                break
    
    # 处理目录占满所有检查页的情况
    if toc_start is not None and toc_end is None:
        toc_end = max_check_pages - 1
    
    return (toc_start, toc_end) if toc_start is not None else None

# 主逻辑
filelist = glob.glob(path)

for doc_path in tqdm(filelist):
    file_name = os.path.basename(doc_path)
    try:
        doc = fitz.open(doc_path)
        toc_range = get_toc_range(doc)
        if toc_range:
            start, end = toc_range
            print(f"{file_name}: 目录页码范围 {start+1} - {end+1}")  # 转换为人类习惯的页码(从1开始)
        else:
            print(f"{file_name}: 未找到目录")
        doc.close()
    except Exception as e:
        print(f"处理{file_name}出错: {str(e)}")

代码说明

  • is_toc_page函数:通过关键词+结构特征双重验证,判断页面是否为目录页,降低误判率。
  • get_toc_range函数:遍历页面查找目录起始页,向后验证直到非目录页,返回目录的起止页码(PDF内部页码从0开始,输出时转换为从1开始)。
  • 主逻辑:遍历所有PDF文件,输出每个文件的目录页码范围。

内容的提问来源于stack exchange,提问作者Harshal Naik

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 12:12:14