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
相关产品推荐
相关产品推荐

