上一篇
Python提取PDF文本数字 - 详细教程与代码示例
- Python
- 2025-08-12
- 1041
Python提取PDF文本数字的详细教程
在数据分析、财务报告处理和信息提取工作中,经常需要从PDF文档中提取数字数据。本教程将详细介绍如何使用Python高效地从PDF文件中提取文本和数字。
为什么需要从PDF提取数字?
PDF是存储报告、发票和财务文档的常用格式,但提取其中的结构化数据却很困难。常见应用场景包括:
- 财务报告中的金额数据提取
- 科学研究论文中的数值结果收集
- 发票处理系统中的自动化数据录入
- 市场分析报告中的统计数字抓取
Python库选择与安装
Python有几个优秀的PDF处理库:
库名称 | 特点 | 安装命令 |
---|---|---|
pdfplumber | 提取文本准确,支持表格提取,简单易用 | pip install pdfplumber |
PyPDF2 | 基础PDF操作,文本提取功能有限 | pip install PyPDF2 |
pdfminer.six | 强大的文本提取,但API较复杂 | pip install pdfminer.six |
本教程将使用pdfplumber,因为它提供了直观的API和出色的文本提取能力。
PDF文本提取基础
使用pdfplumber提取PDF文本的基本方法:
示例代码:提取整个PDF文本
import pdfplumber def extract_text_from_pdf(pdf_path): all_text = "" with pdfplumber.open(pdf_path) as pdf: for page in pdf.pages: text = page.extract_text() if text: all_text += text + "\n" return all_text # 使用示例 pdf_text = extract_text_from_pdf("财务报告.pdf") print(pdf_text)
这段代码会遍历PDF的每一页,提取所有文本内容并合并为一个字符串。
使用正则表达式提取数字
从提取的文本中识别数字需要正则表达式:
数字提取函数
import re def extract_numbers(text): # 匹配整数、小数、科学计数法、带逗号的数字 pattern = r"[-+]?\d{1,3}(?:,\d{3})*(?:\.\d+)?(?:[eE][-+]?\d+)?" numbers = re.findall(pattern, text) # 清理数字格式(移除逗号) cleaned_numbers = [num.replace(",", "") for num in numbers] # 转换为合适的数值类型 final_numbers = [] for num in cleaned_numbers: try: # 尝试转换为浮点数 n = float(num) # 如果是整数,转换为int if n.is_integer(): final_numbers.append(int(n)) else: final_numbers.append(n) except ValueError: continue return final_numbers # 使用示例 numbers = extract_numbers(pdf_text) print("提取到的数字:", numbers)
这个函数可以识别各种格式的数字:
- 整数:
42
,-15
,1,000
- 小数:
3.14
,-0.5
- 科学计数法:
1.23e-4
- 带千位分隔符:
12,345.67
表格数据处理技巧
PDF中的表格数据需要特殊处理:
提取表格数据
def extract_tables_from_pdf(pdf_path): all_tables = [] with pdfplumber.open(pdf_path) as pdf: for page in pdf.pages: tables = page.extract_tables() for table in tables: # 处理表格数据 processed_table = [] for row in table: processed_row = [cell.replace("\n", " ") if cell else "" for cell in row] processed_table.append(processed_row) all_tables.append(processed_table) return all_tables # 使用示例 tables = extract_tables_from_pdf("财务报告.pdf") for i, table in enumerate(tables): print(f"表格 {i+1}:") for row in table: print(row)
提取表格后,可以进一步处理其中的数字:
# 从表格中提取数字 for table in tables: for row in table: for cell in row: # 检查单元格是否包含数字 if any(char.isdigit() for char in cell): # 提取并处理数字 cell_numbers = extract_numbers(cell) if cell_numbers: print(f"在单元格 '{cell}' 中找到数字: {cell_numbers}")
完整代码示例
完整的PDF数字提取脚本:
import pdfplumber import re def extract_pdf_numbers(pdf_path): """从PDF文件中提取所有数字""" all_numbers = [] with pdfplumber.open(pdf_path) as pdf: for page in pdf.pages: # 提取文本 text = page.extract_text() if text: all_numbers.extend(extract_numbers(text)) # 提取表格中的数字 tables = page.extract_tables() for table in tables: for row in table: for cell in row: if cell: all_numbers.extend(extract_numbers(cell)) return all_numbers def extract_numbers(text): """从文本中提取数字""" pattern = r"[-+]?\d{1,3}(?:,\d{3})*(?:\.\d+)?(?:[eE][-+]?\d+)?" numbers = re.findall(pattern, text) cleaned_numbers = [num.replace(",", "") for num in numbers] final_numbers = [] for num in cleaned_numbers: try: n = float(num) if n.is_integer(): final_numbers.append(int(n)) else: final_numbers.append(n) except ValueError: continue return final_numbers if __name__ == "__main__": pdf_file = "财务报告.pdf" numbers = extract_pdf_numbers(pdf_file) print(f"从 {pdf_file} 中提取到 {len(numbers)} 个数字:") print(numbers) # 保存到CSV文件 with open("extracted_numbers.csv", "w") as f: f.write("Extracted Numbers\n") for num in numbers: f.write(f"{num}\n") print("结果已保存到 extracted_numbers.csv")
常见问题与解决方案
Q: 提取的数字不准确或遗漏
解决方案:
- 调整正则表达式模式以匹配特定格式
- 检查PDF是否是扫描件(图片)而非可搜索文本
- 尝试不同的PDF库(如pdfminer.six)
Q: 表格提取混乱
解决方案:
- 使用pdfplumber的
table_settings
参数调整表格检测 - 尝试
extract_table()
替代extract_tables()
- 处理前使用
page.debug_tablefinder()
可视化表格检测
Q: 性能问题(大文件处理慢)
解决方案:
- 使用多线程/多进程处理页面
- 仅处理特定页面范围
- 对于纯数据PDF,考虑转换为其他格式(如Excel)
总结
本教程详细介绍了使用Python从PDF文件中提取数字的完整流程:
- 使用pdfplumber提取PDF文本和表格内容
- 应用正则表达式识别各种格式的数字
- 清理和转换数字格式
- 处理表格中的特殊数据
- 保存提取结果
通过这个方法,你可以自动化处理财务报告、研究论文、商业分析等各种PDF文档中的数据提取任务,大大提高工作效率。
本文由JiangMengSun于2025-08-12发表在吾爱品聚,如有疑问,请联系我们。
本文链接:https://521pj.cn/20257918.html
发表评论