
tabula-py 是 tabula-java 的 python 封装,一个功能强大的工具,专门用于从 pdf 文件中提取表格数据。它尤其擅长处理那些结构不规则、包含扫描图像或没有明确文本层的 pdf 中的表格。tabula-py 能够将提取的结果直接转换为 pandas dataframe 对象,这极大地简化了后续的数据清洗、分析和存储工作。
在没有指定任何高级参数的情况下,tabula-py 会尝试通过启发式算法自动识别 PDF 中的表格结构。对于一些布局简单、数据清晰的表格,这种默认方法可能已经足够。
基础提取示例代码:
import tabula
import pandas as pd
# 请替换为你的PDF文件路径
pdf_path = "your_document.pdf"
print("--- 基础提取结果 ---")
try:
# 使用默认参数进行提取
# pages='all' 表示提取所有页面的表格
# multiple_tables=True 表示尝试提取页面上的所有表格
tables_default = tabula.read_pdf(pdf_path, pages='all', multiple_tables=True)
for i, df in enumerate(tables_default):
print(f"Table {i + 1} (基础提取):\n{df}\n")
except FileNotFoundError:
print(f"错误:文件 '{pdf_path}' 未找到。请检查路径。")
except Exception as e:
print(f"基础提取发生错误: {e}")然而,正如在实际应用中经常遇到的,这种默认提取方式对于结构复杂、边框不完整或布局特殊的表格,往往无法完美捕捉所有细节。常见的问题包括:
当 PDF 中的表格具有清晰的线条(即“格子”结构,如传统电子表格)时,tabula-py 提供了一个关键参数 lattice=True 来显著提升提取精度。此参数指示 tabula 采用基于格线的识别算法,能够更准确地识别表格的边界和单元格。这对于那些看起来像传统电子表格的表格尤其有效。
立即学习“Python免费学习笔记(深入)”;
使用 lattice=True 提取示例代码:
import tabula
import pandas as pd
pdf_path = "your_document.pdf" # 请替换为你的PDF文件路径
print("--- 使用 lattice=True 提取结果 ---")
try:
# 启用 lattice=True 参数
tables_lattice = tabula.read_pdf(
pdf_path,
pages='all',
multiple_tables=True,
lattice=True # 关键参数:启用格线识别模式
)
for i, df in enumerate(tables_lattice):
print(f"Table {i + 1} (使用 lattice=True):\n{df}\n")
except FileNotFoundError:
print(f"错误:文件 '{pdf_path}' 未找到。请检查路径。")
except Exception as e:
print(f"lattice=True 提取发生错误: {e}")通过设置 lattice=True,通常可以显著改善提取结果,使表格结构更加完整和准确。但即使如此,有时仍会引入一些不必要的“Unnamed: X”列,这些列通常是由于表格布局的细微差异或 tabula 识别上的模糊性造成的。
tabula.read_pdf 函数返回的是 Pandas DataFrame 对象的列表,这使得我们可以利用 Pandas 强大的数据清洗功能来移除提取过程中可能产生的冗余列,例如 Unnamed: X 格式的列。
识别并移除冗余列的方法:
示例代码(移除冗余列):
import tabula
import pandas as pd
pdf_path = "your_document.pdf" # 请替换为你的PDF文件路径
# 假设 tables_lattice 已经通过 lattice=True 提取
try:
tables_lattice = tabula.read_pdf(
pdf_path,
pages='all',
multiple_tables=True,
lattice=True
)
except Exception as e:
print(f"提取表格时发生错误: {e}")
exit()
cleaned_tables = []
if tables_lattice:
print("\n--- 正在对提取的表格进行清洗 ---")
for i, df in enumerate(tables_lattice):
print(f"\n--- 处理表格 {i + 1} ---")
print("原始表格前几行:\n", df.head())
# 复制 DataFrame 以免修改原始数据
current_df = df.copy()
# 识别并移除包含 'Unnamed' 的列
# 这里使用 str(col) 以防列名不是字符串类型
cols_to_drop = [col for col in current_df.columns if 'Unnamed' in str(col)]
if cols_to_drop:
print(f"发现并移除冗余列: {cols_to_drop}")
current_df = current_df.drop(columns=cols_to_drop)
else:
print("未发现冗余 'Unnamed' 列。")
# 进一步清洗:处理可能的空行或非标题行
# 示例:如果第一行所有值都是NaN(即全为空),则删除第一行
if not current_df.empty and current_df.iloc[0].isnull().all():
print("检测到第一行为空行,已移除。")
current_df = current_df.iloc[1:].reset_index(drop=True)
# 重置索引(可选,如果之前删除了行)
current_df = current_df.reset_index(drop=True)
cleaned_tables.append(current_df)
print(f"清洗后表格 {i + 1} 前几行:\n", current_df.head())
else:
print("未提取到任何表格,无需清洗。")以下是一个结合了 lattice=True 提取和后续列清洗的完整脚本,旨在实现 PDF 表格的精确提取与清洗:
import tabula
import pandas as pd
# 指定你的 PDF 文件路径
pdf_path = "your_document.pdf" # <-- 请务必替换为你的PDF文件路径
# 1. 使用 lattice=True 参数进行表格提取
print("--- 正在使用 lattice=True 提取表格 ---")
try:
# pages='all' 提取所有页面的表格
# multiple_tables=True 尝试提取页面上的所有表格
# lattice=True 启用基于格线的识别模式,适用于有清晰边框的表格
extracted_tables = tabula.read_pdf(
pdf_path,
pages='all',
multiple_tables=True,
lattice=True,
# encoding='utf-8' # 如果出现乱码,可以尝试指定编码
)
print(f"成功提取到 {len(extracted_tables)} 个表格。")
except FileNotFoundError:
print(f"错误:文件 '{pdf_path}' 未找到。请检查路径。")
exit()
except Exception as e:
print(f"提取表格时发生错误: {e}")
exit()
# 2. 对每个提取到的 DataFrame 进行后处理(移除冗余列)
final_cleaned_tables = []
if extracted_tables:
print("\n--- 正在对提取的表格进行清洗 ---")
for i, df in enumerate(extracted_tables):
print(f"\n--- 处理表格 {i + 1} ---")
print("原始表格前几行:\n", df.head().to_string()) # 使用 .to_string() 避免截断
# 识别并移除包含 'Unnamed' 的列
cols_to_drop = [col for col in df.columns if 'Unnamed' in str(col)]
if cols_to_drop:
print(f"发现并移除冗余列: {cols_to_drop}")
df_cleaned = df.drop(columns=cols_to_drop)
else:
df_cleaned = df.copy() # 如果没有冗余列,也复制一份
print("未发现冗余 'Unnamed' 列。")
# 进一步清洗:检查并处理可能的空行或非数据行
# 例如,如果第一行所有值都是NaN,则删除第一行
if not df_cleaned.empty and df_cleaned.iloc[0].isnull().all():
print("检测到第一行为空行,已移除。")
df_cleaned = df_cleaned.iloc[1:].reset_index(drop=True)
final_cleaned_tables.append(df_cleaned)
print(f"清洗后表格 {i + 1} 前几行:\n", df_cleaned.head().to_string())
else:
print("未提取到任何表格,无需清洗。")
# 3. 展示最终结果或保存
print("\n--- 最终清洗后的表格数据 ---")
for i, df in enumerate(final_cleaned_tables):
print(f"\n最终表格 {i以上就是Python Tabula 库高级用法:实现 PDF 表格的精确提取与清洗的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号