PDF发票数据提取代码报错:AttributeError: 'NoneType' object无'group'属性
问题解决:AttributeError: 'NoneType' object has no attribute 'group' 及PDF发票数据提取优化
错误根源
- 正则表达式语法错误:你用
d\+匹配数字,但正确的数字匹配正则是\d+,少了反斜杠导致完全匹配不到目标内容,re.search返回None,调用group()自然触发错误。 - 未做匹配失败兜底:即便正则写对,也可能遇到格式特殊的PDF,直接调用
group()会导致程序崩溃。 - 数据结构处理错误:
flat_data把每个PDF的四条数据拆成单个元素,生成的Excel只会有一列,完全不符合预期结构。
修复后的完整代码
import pandas as pd import os import pdfplumber import re # 读取基础Excel(若不需要可直接删除这段) path_base = rf'C:/Users/{os.getlogin()}/OneDrive - Falabella/Documentos - Desarrollo Logistico/Proyectos Desarrollo Interno/Proyectos Internos/Confimación y Facturación Apple/Base proveedor/Base-prueba.xlsx' detalle_base = pd.read_excel(path_base, sheet_name="Base") detalle_base = detalle_base.reindex(columns=[ 'Factura', 'New OC', 'PRODUCTO', 'NOMBRE', 'Units', 'CAJAS', 'SKU Falabella', 'Costo Unitario', 'Monto total', 'Diferencia Informada', 'Comentarios' ]) def extract_pdf_data(file_names): all_data = [] for file_name in file_names: with pdfplumber.open(file_name) as pdf: page = pdf.pages[0] text = page.extract_text() # 修复正则+添加匹配失败兜底 num_fact_match = re.search(r'N°\s*(\d+)', text) numero_factura = num_fact_match.group(1) if num_fact_match else '未找到' cant_match = re.search(r'Cant\.\s*(\d+)', text) cantidad = cant_match.group(1) if cant_match else '未找到' costo_match = re.search(r'Valor unitario\s*(\d+\.?\d*)', text) costo_unitario_fact = costo_match.group(1) if costo_match else '未找到' total_match = re.search(r'Valor\s*(\d+\.?\d*)', text) valor_total_fact = total_match.group(1) if total_match else '未找到' all_data.append([numero_factura, cantidad, costo_unitario_fact, valor_total_fact]) return all_data def convert_pdfs_to_excel(directory, excel_save_path): # 兼容大小写后缀的PDF文件 file_names = [ os.path.join(directory, f) for f in os.listdir(directory) if f.lower().endswith('.pdf') ] all_data = extract_pdf_data(file_names) # 直接用二维列表生成DataFrame,保证四列结构 df = pd.DataFrame( all_data, columns=['Numero Factura', 'Cantidad', 'Costo Unitario', 'Valor Total'] ) df.to_excel(excel_save_path, index=False) # 执行调用 pdf_directory = rf'C:/Users/{os.getlogin()}/OneDrive - Falabella/Documentos - Desarrollo Logistico/Proyectos Desarrollo Interno/Proyectos Internos/Confimación y Facturación Apple/Facturas Apple' excel_output_path = rf'C:/Users/{os.getlogin()}/OneDrive - Falabella/Documentos - Desarrollo Logistico/Proyectos Desarrollo Interno/Proyectos Internos/Confimación y Facturación Apple/datos.xlsx' convert_pdfs_to_excel(pdf_directory, excel_output_path)
核心修复说明
- 正则修正:把
d\+改成\d+匹配整数,金额类字段用\d+\.?\d*兼容整数和小数格式。 - 容错机制:每次匹配后先判断是否找到结果,未匹配到则填充“未找到”,避免程序崩溃。
- 数据结构修复:删除错误的
flat_data处理,直接用每个PDF对应的列表生成Excel行,保证四列的正确结构。 - 路径优化:用f-string简化路径拼接,同时兼容大写后缀的PDF文件。
额外提示
- 如果部分发票是表格形式,
pdfplumber的extract_table()方法比纯文本提取更靠谱,可以尝试用它直接提取结构化表格数据。 - 可添加打印语句输出正在处理的文件名,方便排查单个PDF的提取异常。
内容的提问来源于stack exchange,提问作者Ingrid
相关产品推荐
相关产品推荐

