多栏 PDF 的阅读顺序
论文、手册常见双栏排版:直接按文本流抽取,会得到左栏第一行、右栏第一行、左栏第二行这样的交错序列,句子被拆成两半再重新拼接,语义在解析阶段就被破坏,后续切分与向量化再怎么优化都补不回来。正确做法是按坐标分栏排序,或直接交给版面分析模型输出阅读顺序,并在解析后抽样人工核对。
基本信息
| 适用对象 | 双栏/三栏排版的论文、期刊、说明书 PDF |
|---|---|
| 常见库 | PyMuPDF(fitz)取文本块坐标、pdfplumber 取字符坐标 |
| 判定依据 | 文本块的 x 坐标相对页面中线偏左还是偏右 |
| 可靠替代 | 版面分析工具(如 MinerU、Marker)输出的阅读顺序 |
| 验收方式 | 抽样比对转换后文本与原 PDF 的阅读顺序 |
典型使用场景
- 学术论文入库:公式与正文交错,顺序错则切片语义全废
- 产品说明书解析:图文混排且存在跨栏大标题
- 批量入库前的质量门禁:对每份 PDF 计算“跨栏交错率”作为异常信号
- 混合策略:先按形状判断栏数,单栏文档走便宜的直接抽取
- 与版面分析工具对照:同一份文档两条链路的结果差异,用于选型
按坐标简易分栏
按坐标简易分栏
import fitz
page = fitz.open('paper.pdf')[0]
blocks = page.get_text('blocks') # (x0, y0, x1, y1, text, ...)
mid = page.rect.width / 2
left = sorted([b for b in blocks if b[2] <= mid + 5], key=lambda b: b[1])
right = sorted([b for b in blocks if b[0] >= mid - 5], key=lambda b: b[1])
for b in left + right: # 先左栏后右栏
print(b[4][:60])分栏判据与风险
| 情况 | 处理方式 | 风险 |
|---|---|---|
| 标准双栏 | 按中线左右分组再各自按 y 排序 | 跨栏元素被误分 |
| 整宽大标题 | 按整宽先切段落带,再处理栏内 | 漏判会切断章节归属 |
| 跨栏表格或图 | 整块保留并挂到最近的段落 | 被拆到两栏导致表格错行 |
| 单栏混排 | 直接按 y 排序即可 | 误判成多栏反而打乱顺序 |
简易坐标分栏对跨栏标题、整宽图表会误判:生产环境建议用版面分析模型输出阅读顺序,再对样本逐页抽检,不能只看首页效果就批量入库。