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

PyPDF2提取PDF文本顺序异常,如何实现从上到下从左到右读取?

解决PDF发票文本提取顺序混乱的方案

问题根源

PyPDF2提取文本依赖PDF内部的文本对象存储顺序,和视觉上的从上到下、从左到右顺序不一致;Tesseract默认布局分析未适配发票的表格排版,导致部分文件提取异常。

可行解决方案

1. 使用PyMuPDF(fitz)提取视觉顺序文本

PyMuPDF的文本提取逻辑更贴近人类阅读的视觉顺序,尤其适合表格类文档,对多数规范排版的发票效果较好。

安装依赖:

pip install pymupdf

示例代码:

import fitz  # PyMuPDF

def extract_invoice_text(invoice_path):
    doc = fitz.open(invoice_path)
    page = doc[0]
    # 按视觉顺序提取文本,参数确保优先按行排列
    text = page.get_text("text", sort=True)
    print(text)
    doc.close()
    return text

# 调用
extract_invoice_text("your_invoice.pdf")

2. 优化Tesseract的布局分析与预处理

针对扫描版或OCR识别的PDF,调整Tesseract的PSM(页面分割模式)参数,配合图片预处理提升识别准确性。

安装依赖:

pip install pytesseract pillow

示例代码:

import pytesseract
from PIL import Image
import fitz  # 用于将PDF页转为图片

def ocr_invoice(invoice_path):
    doc = fitz.open(invoice_path)
    page = doc[0]
    # 将PDF页转为高分辨率图片,提升识别效果
    pix = page.get_pixmap(dpi=300)
    img = Image.frombytes("RGB", [pix.width, pix.height], pix.samples)
    
    # 图片预处理:灰度化+二值化,减少干扰
    img = img.convert('L')
    img = img.point(lambda x: 0 if x < 127 else 255, '1')
    
    # 设置Tesseract参数:--psm 6适用于单一均匀文本块(如表格),零散文本可尝试--psm 11
    custom_config = r'--oem 3 --psm 6 -l chi_sim'
    text = pytesseract.image_to_string(img, config=custom_config)
    print(text)
    doc.close()
    return text

# 调用
ocr_invoice("your_invoice.pdf")

3. 用表格提取工具直接获取结构化数据

发票商品信息通常是表格结构,使用Camelot或Tabula可以直接提取表格数据,避免文本顺序问题,直接得到商品描述、数量、价格的结构化结果。

使用Camelot:

安装依赖:

pip install camelot-py[cv]

示例代码:

import camelot

def extract_invoice_table(invoice_path):
    # 读取PDF中的表格,调整参数适配发票排版
    tables = camelot.read_pdf(invoice_path, pages='1', flavor='stream')
    # 假设第一个表格是商品信息表
    if tables:
        df = tables[0].df
        print(df)
        # 将结果保存为CSV方便后续处理
        df.to_csv("invoice_items.csv", index=False)
    return tables

# 调用
extract_invoice_table("your_invoice.pdf")

使用Tabula:

安装依赖:

pip install tabula-py

示例代码:

import tabula

def extract_tabula_table(invoice_path):
    # 提取页面内所有表格
    dfs = tabula.read_pdf(invoice_path, pages='1', multiple_tables=True)
    # 遍历找到包含商品信息的表格(通过表头匹配)
    for df in dfs:
        if "商品描述" in df.columns or "数量" in df.columns:
            print(df)
            df.to_csv("invoice_items.csv", index=False)
            break
    return dfs

# 调用
extract_tabula_table("your_invoice.pdf")

选择建议

  • 若发票是可编辑PDF(非扫描件),优先用PyMuPDF快速提取视觉顺序文本,再通过字符串处理或正则提取目标字段;
  • 若发票是扫描件(图片转PDF),用优化后的Tesseract配合图片预处理;
  • 若商品信息是标准表格,直接用Camelot/Tabula提取结构化数据,效率最高且准确率有保障。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 02:07:10