如何按章节从PDF提取文本并输出为JSON格式?
PDF结构化提取的实用方案
几种靠谱的解决思路
PyMuPDF+规则+语义分析组合拳
先用PyMuPDF把PDF里的所有文本块提取出来,每个块会带坐标、字体大小、样式这些元数据。像Dart规范这种正式文档,标题一般字号更大、加粗,章节编号也有规律(1、2、3或者1.1、1.2这种)。先筛出符合标题特征的块,再根据上下位置、章节编号的层级关系,把章节的父子结构搭起来。然后把每个标题下面、下一个标题上面的正文文本拼起来,对应到章节的text字段里。
碰到像“Normative References”这种带子项的章节,直接通过子项的编号(1、2)或者字体/位置特征识别,把它们做成数组元素塞到对应章节下就行。用pdfplumber做精细布局分析
pdfplumber比PyMuPDF能拿到更细的文本元数据,比如每个单词的位置、字体。你可以用它的extract_words()方法把所有单词的信息提出来,然后按字体大小、位置聚类出标题和正文,再用正则表达式(比如匹配^\d+(\.\d+)*\s+这种章节编号格式)识别层级,自动把正文和对应标题关联起来。这种方法对没有缩进的PDF兼容性更好。轻量深度学习辅助布局分类
不用搞复杂的Detectron2,直接用layout-parser的预训练出版物模型,就能识别出“标题”“正文”“列表项”这些布局类型。先按页面排序,同一页内按y坐标从上到下排,再根据章节编号的层级把这些元素拼成树状结构,最后把对应文本整理成你要的JSON格式。这种方法比纯规则更稳,能应付各种排版的情况。
简单实现示例(PyMuPDF+规则)
- 先提取所有文本块:
import fitz doc = fitz.open("Dart.pdf") all_blocks = [] for page in doc: # get_text("blocks")返回(x0, y0, x1, y1, text, block_no, type) page_blocks = page.get_text("blocks") all_blocks.extend(page_blocks) - 筛选标题:用正则匹配章节编号,再结合字体大小(比如字号>12且加粗)挑出标题块,记录每个标题的位置和层级。
- 按y坐标排序所有块,遍历每个标题,把下一个标题之前的正文文本拼接起来,作为该章节的内容。
- 处理子列表章节:识别子项的编号,把它们整理成数组加到对应章节下。
关键注意点
- 正式规范文档的章节编号格式很固定,正则表达式是核心,比如
^(\d+)\s+([A-Za-z\s]+)匹配一级章节,^(\d+\.\d+)\s+匹配二级章节。 - 跨页章节要注意跟踪当前章节,把跨页的正文都归到上一个章节里。
内容的提问来源于stack exchange,提问作者Tim
相关产品推荐
相关产品推荐

