本文介绍使用pdftohtml工具将法律合同类pdf精准转换为带语义标签(如h1–h6、p)的html,再借助beautiful soup解析标题与正文并分段导出为独立文本文件的完整流程。
在处理结构清晰但无交互能力的PDF文档(如标准法律合同)时,直接提取“标题+对应内容”是常见需求。由于PDF本质是布局导向而非语义导向,无法直接读取逻辑章节,因此需借助语义重建策略:先将PDF转换为结构化HTML(保留标题层级与段落关系),再通过DOM解析实现精准切分。
pdftohtml 是成熟稳定的开源工具(基于Poppler),能将PDF中识别出的视觉层级(如字体大小、加粗、缩进等启发式特征)映射为HTML语义标签(如
),特别适合格式规整的合同类文档。
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,再进行转换。
安装依赖:
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")最终,你将获得一组命名清晰、内容完整的 .txt 文件,每份严格对应合同中的一个逻辑章节——无需人工复制粘贴,真正实现法律文档的结构化复用。