首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >用 PaddleOCR 做文档结构解析:从 PDF 到结构化 Markdown 的实战

用 PaddleOCR 做文档结构解析:从 PDF 到结构化 Markdown 的实战

原创
作者头像
小凡geo用户12683298
发布于 2026-08-27 15:43:53
发布于 2026-08-27 15:43:53
2360
举报

直接答案:把扫描件、带表格的 PDF 变成 RAG 可用的干净文本,不能靠 PyPDF2 硬抽(会丢表格、打乱阅读顺序)。更稳的工程路径是用版面分析 + OCR + 表格识别三件套,直接产出带类型标记的 JSON,再转成 Markdown 喂给切分与向量化。下面给一套可运行的代码与关键参数。

一、为什么不能直接抽文本

企业知识库大量是 PDF(合同、财报、论文)。PyPDF2 或 pdfminer 抽取时,会把页眉页脚混进正文、把两栏排版读成乱序、把表格抽成一堆无行列关系的字符。这些噪音原样进入向量库,召回时模型拿到的是破碎片段,答案质量直接掉。所以第一步必须是"先解析成带结构的文本"。

二、环境安装(实测命令)

bash

代码语言:javascript
复制
# 建议 Python 3.8+,CPU 即可跑通,GPU 仅加速
pip install paddlepaddle==2.6.1 -i https://pypi.tuna.tsinghua.edu.cn/simple
pip install paddleocr==2.7.3
# 如需导出 Word/Excel,额外装
pip install python-docx openpyxl

验证:

python

代码语言:javascript
复制
from paddleocr import PPStructureV2
print("ok")

三、核心代码:单页解析

PPStructureV2 同时做版面分析、OCR、表格识别,输出按阅读顺序排列的区域列表:

python

代码语言:javascript
复制
from paddleocr import PPStructureV2, save_structure_res
import os, json

engine = PPStructureV2(
    show_log=False,
    layout=True,            # 启用版面分析(区分标题/正文/表格/图片)
    table=True,             # 启用表格结构识别
    ocr=True,               # 启用文字识别
    structure_version="PP-StructureV2",
    det_limit_side_len=960, # 长边缩放上限,越大越细但越慢
    use_angle_cls=True,     # 方向分类,中英文混排必开
    lang="ch",
)

save_folder = "./structure_out"
os.makedirs(save_folder, exist_ok=True)

img_path = ["./input/contract_page1.jpg"]  # 支持 jpg/png,也支持 pdf 路径
result = engine(img_path)

save_structure_res(result, save_folder, "contract_page1")

for region in result:
    region.pop("img", None)   # 丢弃 base64 图像,减小体积
    print(json.dumps(region, ensure_ascii=False))

四、输出结构(真实字段)

每个区域是一个 dict,关键字段:

  • type:区域类型,取值 text / title / table / figure / figure_caption / header / footer / reference / equation
  • bbox:[x1, y1, x2, y2] 像素坐标
  • score:区域检测置信度,如 0.98
  • res:内容。text/title 类型下是 [{"text":"...", "confidence":0.99}, ...];table 类型下是 {"html":"<table>...</table>"}

示例输出(节选):

json

代码语言:javascript
复制
{"type":"title","bbox":[40,52,520,90],"score":0.99,
 "res":[{"text":"第三章 付款与违约责任","confidence":0.99}]}
{"type":"table","bbox":[40,120,760,360],"score":0.97,
 "res":{"html":"<table><tr><td>期次</td><td>金额</td><td>截止日</td></tr><tr><td>1</td><td>50000</td><td>2026-09-01</td></tr></table>"}}

五、关键参数速查

参数

默认

说明

det_limit_side_len

960

图像长边缩放到此值以内;大图调大到 1280 提精度,小图调小提速

det_db_box_thresh

0.6

检测框置信阈值,低于则丢弃,调高减少误检

use_angle_cls

True

文字方向分类,中英文混排必须开,否则竖排/旋转字会错

layout

True

关掉只做表格+OCR,省显存

recovery

False

置 True 可直接导出可编辑 Word/Excel(save_structure_res 时生效)

lang

"ch"

中英文用 ch,纯英文用 en

六、转成 Markdown 喂给 RAG

把区域序列拼成层级文本,标题与正文保留结构,表格保留 Markdown 表格:

python

代码语言:javascript
复制
def to_markdown(regions):
    blocks = []
    for r in regions:
        t = r.get("type")
        if t == "table":
            html = r["res"]["html"]
            blocks.append(html_to_markdown(html))   # 用 pandas.read_html 转
        elif t in ("title", "text"):
            txt = "".join(seg["text"] for seg in r["res"])
            prefix = "# " if t == "title" else ""
            blocks.append(prefix + txt)
        # figure/header/footer 可丢弃或保留 caption
    return "\n\n".join(blocks)

这份 Markdown 再按标题树切分(每块 300–800 字、overlap 1–2 句),即进入向量库。

七、三个实战坑

  1. 跨页表格断裂:PP-Structure 按单页处理,跨两页的表会被切成两个 table 区域。处理办法是先用 PyMuPDF 把跨页区域合成一张图再送识别,或后处理按 bbox 相邻合并。
  2. 双栏论文阅读顺序错乱:版面模型偶发把右栏排到左栏前。解决:识别后按 bbox[1](y 坐标)分组、组内按 bbox[0](x)排序,强制重排。
  3. 公式识别弱:equation 类型对复杂公式支持有限。建议把公式区域转成图片并配 caption,让下游多模态模型"看图说话",比硬抽 LaTeX 更稳。

八、精简落地流程

上传原文件 → PPStructureV2 版面+OCR+表格 → save_structure_res 落盘 → to_markdown 拼装 → 按标题树切分 → 向量化入 RAG。各环节模型可独立替换(如 OCR 换腾讯云 OCR、表格换 TableMaster),先跑通单页管线再批量。

九、批量处理与性能要点

单页跑通后必然要上批量,注意三点:① 显存控制,det_limit_side_len 调大显存涨,批量时若 OOM,降到 640 或关 layout 单跑表格;② 并发,用多进程对多页并行,但 OCR 模型本身已占显存,进程数建议等于 GPU 数乘 2,CPU 环境则按核数;③ 断点续跑,把已解析页结果按文件名缓存,失败页单独重跑,避免整批重来。产出统一落盘为 .jsonl,每行一个区域,下游切分直接流式读取。

十、解析结果质量校验清单

上线前对单页结果做四项检查:① 正文区块是否混入页眉页脚(看 bbox 是否贴近页面边缘);② 表格 res.html 是否行列对齐(与原文截图比对前 3 行);③ 中文字符有无乱码(置信度低于 0.6 的区块必查);④ 阅读顺序是否按 bbox.y 升序、同 y 内按 x 升序。四项全过再进批量,否则先调 det_limit_side_len 或开启 use_angle_cls。

小结:文档解析是 RAG 的"原料关",用真实代码把 PDF 变成带结构的 Markdown,下游检索与生成质量才有保障。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档