You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用PyMuPDF(fitz)提取多栏PDF文本时顺序异常的问题求助

解决PyMuPDF提取多栏PDF文本顺序混乱的问题

当处理多栏PDF时,sort=True的全局排序逻辑(按块坐标从上到下、从左到右)会导致文本顺序错乱——它会把所有文本块按全局位置排序,而非遵循"左栏从上到下读完再读右栏"的自然阅读顺序,这就是你遇到第一段文本跑到中间的原因。

解决方案:按栏分组排序文本块

核心思路是先识别页面的栏布局,将同一栏的文本块归为一组,再对每组内的块按垂直位置排序,最后按栏的左右顺序拼接文本。

以下是可直接运行的代码实现:

import fitz

def extract_multi_column_text(page):
    # 获取页面所有文本块(过滤非文本块)
    blocks = page.get_text("dict", sort=True)["blocks"]
    text_blocks = [block for block in blocks if block["type"] == 0]
    
    if not text_blocks:
        return ""
    
    # 计算分组阈值:用首个文本块宽度的10%作为栏间距判断标准
    first_block_width = text_blocks[0]["bbox"][2] - text_blocks[0]["bbox"][0]
    col_threshold = first_block_width * 0.1
    
    # 按块的左边界x坐标排序,再聚类分组(区分不同栏)
    sorted_blocks = sorted(text_blocks, key=lambda b: b["bbox"][0])
    columns = []
    current_column = [sorted_blocks[0]]
    
    for block in sorted_blocks[1:]:
        prev_block_x = current_column[-1]["bbox"][0]
        # 若当前块与组内最后一块的左边界差小于阈值,归为同一栏
        if block["bbox"][0] - prev_block_x < col_threshold:
            current_column.append(block)
        else:
            columns.append(current_column)
            current_column = [block]
    columns.append(current_column)
    
    # 按栏顺序拼接文本:每栏内按垂直位置(y坐标)从上到下排序
    final_text = ""
    for col in columns:
        sorted_col = sorted(col, key=lambda b: b["bbox"][1])
        for block in sorted_col:
            # 提取块内所有文本片段
            for line in block["lines"]:
                for span in line["spans"]:
                    final_text += span["text"] + " "
            final_text += "\n\n"
    
    return final_text

# 使用示例
doc = fitz.open("你的多栏PDF文件.pdf")
target_page = doc[0]  # 取第一页示例
extracted_text = extract_multi_column_text(target_page)
print(extracted_text)

代码说明

  1. 过滤文本块:只保留type=0的文本块,排除图片、图形等非文本元素。
  2. 栏分组逻辑:通过文本块的左边界坐标聚类,把位置相近的块归为同一栏,适配大多数等宽多栏布局。
  3. 栏内排序:每栏内的文本块按顶部y坐标排序,保证从上到下的阅读顺序。
  4. 文本拼接:按栏的左右顺序依次拼接每栏的文本,还原自然阅读流。

如果遇到不等宽栏、嵌套栏等复杂布局,可以进一步优化分组逻辑(比如用page.get_text("words")获取单词级坐标,再按栏分组),但上述代码足以覆盖常规多栏PDF的提取需求。

内容的提问来源于stack exchange,提问作者user116936

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 16:05:26