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

如何用Python识别需拆分的多语言PDF文档?

多语言双栏PDF拆分识别方案(Python实现)

核心思路

要判断PDF是否需要垂直拆分(分离不同语言的双栏),核心验证两点:

  1. 页面文本块呈现明显的左右双栏分布
  2. 左右两栏的文本语言为两种不同的目标语言(如荷兰语+法语)

依赖库准备

先安装所需工具包:

pip install pymupdf scikit-learn langdetect

具体实现代码

import fitz
from sklearn.cluster import KMeans
from langdetect import detect, LangDetectException

def needs_vertical_split(pdf_path, target_langs=['nl', 'fr'], sample_pages=2):
    """
    判断PDF是否需要垂直拆分(分离多语言双栏)
    :param pdf_path: PDF文件路径
    :param target_langs: 目标语言代码列表(如['nl','fr']对应荷兰语、法语)
    :param sample_pages: 用于分析的样本页数(取前N页)
    :return: True=需要拆分,False=无需拆分
    """
    doc = fitz.open(pdf_path)
    split_needed = 0

    for page_num in range(min(sample_pages, len(doc))):
        page = doc.load_page(page_num)
        blocks = page.get_text("blocks")  # 提取文本块:(x0, y0, x1, y1, text, ...)
        
        # 过滤页眉页脚(保留中间80%高度的文本块)
        page_height = page.rect.height
        valid_blocks = []
        for block in blocks:
            x0, y0, x1, y1, text = block[:5]
            text = text.strip()
            if not text:
                continue
            # 排除顶部10%和底部10%的文本块
            if y0 > page_height * 0.1 and y1 < page_height * 0.9:
                valid_blocks.append(block)
        
        if len(valid_blocks) < 10:  # 文本块太少,跳过该页分析
            continue
        
        # 提取所有文本块的左边界x坐标,用于聚类分析
        x_coords = [[block[0]] for block in valid_blocks]
        kmeans = KMeans(n_clusters=2, random_state=42)
        clusters = kmeans.fit_predict(x_coords)
        
        # 计算聚类中心的距离,判断是否为明显双栏
        cluster_centers = kmeans.cluster_centers_.flatten()
        page_width = page.rect.width
        center_distance = abs(cluster_centers[0] - cluster_centers[1])
        is_two_column = center_distance > page_width * 0.3  # 距离超过页面1/3判定为双栏
        
        if not is_two_column:
            continue
        
        # 分离左右栏文本,检测语言
        left_text = ""
        right_text = ""
        left_center = min(cluster_centers)
        for idx, block in enumerate(valid_blocks):
            if clusters[idx] == (0 if cluster_centers[0] == left_center else 1):
                left_text += block[4] + " "
            else:
                right_text += block[4] + " "
        
        # 检测语言(忽略检测失败的情况)
        try:
            left_lang = detect(left_text)
            right_lang = detect(right_text)
        except LangDetectException:
            continue
        
        # 验证是否为目标语言且不同
        if left_lang in target_langs and right_lang in target_langs and left_lang != right_lang:
            split_needed += 1
    
    doc.close()
    # 超过半数样本页满足条件则判定需要拆分
    return split_needed >= (sample_pages // 2 + 1)

# 测试示例
if __name__ == "__main__":
    # 需拆分的PDF
    print(needs_vertical_split("需要拆分的文件.pdf"))  # 输出True
    # 无需拆分的PDF
    print(needs_vertical_split("无需拆分的文件.pdf"))  # 输出False

关键细节说明

  1. 文本块过滤:排除页眉页脚避免干扰,同时过滤空白文本块,提升分析准确性。
  2. 聚类判断双栏:用K-means对文本块左边界聚类,通过聚类中心距离判断是否为明显双栏,阈值(页面宽度的30%)可根据实际PDF调整。
  3. 语言验证:仅当左右栏为目标语言且不同时,才判定需要拆分,避免误判单栏多语言PDF。
  4. 多页采样:分析前N页取多数结果,避免单页特殊格式(如封面)导致误判。

优化方向

  • 可替换langdetect为更精准的语言检测库(如fasttext),减少检测错误。
  • 针对复杂PDF(如混合单双栏),可增加对每一页单独标记,实现按需拆分指定页面。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 22:11:06