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

12次阅读

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

本文介绍使用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
  • -c:启用css样式(提升结构可读性)
  • -s:生成单文件HTML(非分页碎片)
  • -i:忽略图像(合同文本为主时可提速并减少干扰)

⚠️ 注意: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("nn".join(content))         print(f"✅ 已保存: {filename}")  # 使用示例 split_by_heading("output.html")

3. 进阶建议

  • 验证HTML质量:打开生成的 output.html,检查

    是否真实对应合同中的“第X条”“甲方义务”等标题;若错位,可微调 pdftohtml 参数(如 -zoom 1.5 提升识别精度)或预处理PDF(Acrobat “增强扫描”)。

  • 替代工具对比:pdfplumber(Python库)提供更细粒度的文本定位,适合自定义规则;pymupdf(fitz)速度快,支持直接提取带坐标的文本块,但需自行聚类标题。
  • 批量与自动化:可封装为CLI工具,支持通配符输入(如 *.pdf)及jsON元数据导出(含章节编号、页码范围)。

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

text=ZqhQzanResources