贝利信息

如何将PDF合同按章节提取为结构化HTML或富文本文件

日期:2026-01-17 00:00 / 作者:花韻仙語

本文介绍使用pdftohtml工具将法律合同类pdf精准转换为带语义标签(如h1–h6、p)的html,再借助beautiful soup解析标题与正文并分段导出为独立文本文件的完整流程。

在处理结构清晰但无交互能力的PDF文档(如标准法律合同)时,直接提取“标题+对应内容”是常见需求。由于PDF本质是布局导向而非语义导向,无法直接读取逻辑章节,因此需借助语义重建策略:先将PDF转换为结构化HTML(保留标题层级与段落关系),再通过DOM解析实现精准切分。

✅ 推荐方案:pdftohtml + Python(Beautiful Soup)

pdftohtml 是成熟稳定的开源工具(基于Poppler),能将PDF中识别出的视觉层级(如字体大小、加粗、缩进等启发式特征)映射为HTML语义标签(如

),特别适合格式规整的合同类文档。

1. 安装与基础转换

macOS 用户可通过 Homebrew 安装:

brew install pdftohtml

Windows/Linux 用户可从 pdftohtml 官网 下载二进制包,或使用 poppler-utils 中的 pdftohtml(Ubuntu/Debian):

sudo apt-get install poppler-utils

执行转换(启用结构化输出,保留标题语义):

pdftohtml -c -s -i input_contract.pdf output.html
⚠️ 注意:pdftohtml 的标题识别依赖PDF内嵌字体信息与排版线索。若原PDF为扫描件(图片型),需先用OCR工具(如 pdf2image + pytesseract)转为可搜索PDF,再进行转换。

2. 解析HTML并按章节拆分

安装依赖:

pip install beautifulsoup4

Python 脚本示例(自动识别

标题,并将后续非标题内容归入该节,直到下一标题出现):
from bs4 import BeautifulSoup
import re

def split_by_heading(html_path, output_dir="sections"):
    import os
    os.makedirs(output_dir, exist_ok=True)

    with open(html_path, "r", encoding="utf-8") as f:
        soup = BeautifulSoup(f, "html.parser")

    # 移除脚注、页眉页脚等干扰区域(根据实际HTML结构调整)
    for elem in soup(["script", "style", "footer", "header", "nav"]):
        elem.decompose()

    headings = soup.find_all(re.compile(r"^h[1-6]$"))
    for i, h in enumerate(headings):
        title = h.get_text(strip=True)
        if not title:
            continue

        # 生成安全的文件名(去除非法字符)
        safe_title = re.sub(r'[<>:"/\\|?*]', "_", title)[:50]
        filename = f"{output_dir}/Section_{i+1}_{safe_title}.txt"

        # 收集该标题后所有连续段落(p)、列表(ul/ol)、甚至嵌套div
        content = [title]
        sibling = h.next_sibling
        while sibling and not sibling.name or not re.match(r"^h[1-6]$", sibling.name):
            if sibling.name in ["p", "ul", "ol", "div"] and sibling.get_text(strip=True):
                content.append(sibling.get_text(strip=True))
            sibling = sibling.next_sibling

        with open(filename, "w", encoding="utf-8") as f:
            f.write("\n\n".j

oin(content)) print(f"✅ 已保存: {filename}") # 使用示例 split_by_heading("output.html")

3. 进阶建议

最终,你将获得一组命名清晰、内容完整的 .txt 文件,每份严格对应合同中的一个逻辑章节——无需人工复制粘贴,真正实现法律文档的结构化复用。