当前位置: 代码网 > it编程>前端脚本>Python > Python使用PDFPlumber提取PDF内容的操作指南

Python使用PDFPlumber提取PDF内容的操作指南

2025年12月08日 Python 我要评论
引言处理pdf文件时,你是否遇到过这些难题:想复制表格却格式错乱?提取文本时段落被拆得支离破碎?手动录入pdf数据效率低下还易出错?如果你用过pypdf2、pdfminer等库,可能会发现它们在处理复

引言

处理pdf文件时,你是否遇到过这些难题:想复制表格却格式错乱?提取文本时段落被拆得支离破碎?手动录入pdf数据效率低下还易出错?如果你用过pypdf2、pdfminer等库,可能会发现它们在处理复杂布局(尤其是表格)时力不从心。

pdfplumber 的出现,完美解决了这些痛点。它是一个专注于pdf内容提取的python库,以“精准还原布局”为核心优势,能轻松提取文本、表格,甚至获取文字的位置、字体等细节信息。本文将从基础用法到实战场景,全方位讲解pdfplumber的使用,帮你彻底告别pdf处理的繁琐。

一、为什么选择pdfplumber?

在众多pdf处理库中,pdfplumber的核心竞争力在于:

  • 表格提取精准:自动识别表格边框、合并单元格,提取结果保留表格结构(类似excel),远超pypdf2等库的“纯文本拼接”。
  • 文本提取智能:按页面布局还原文本顺序,避免段落被无序拆分,还能获取文字的坐标、字体、大小等元数据。
  • 操作简单直观:api设计简洁,几行代码即可完成提取,无需深入了解pdf底层格式。
  • 支持细节控制:可指定提取区域(如只提取某页的某块内容)、过滤无效信息,灵活应对复杂pdf。

适合场景:数据分析师提取pdf报表、开发者批量处理合同文本、研究者抓取文献内容等。

二、环境准备:1分钟安装

pdfplumber是纯python库,安装无需依赖复杂的系统工具,直接用pip即可:

pip install pdfplumber

验证安装是否成功:

import pdfplumber
print(pdfplumber.__version__)  # 输出版本号(如 0.9.0)即成功

三、基础用法:从加载pdf到提取内容

pdfplumber的核心流程是:**加载pdf文件→获取页面→提取内容(文本/表格)**。我们从最基础的操作开始,逐步掌握核心功能。

1. 加载pdf并查看页面信息

首先需要用pdfplumber.open()加载pdf文件,然后通过pages属性获取所有页面(按页码顺序排列)。

import pdfplumber

# 加载pdf文件
with pdfplumber.open("example.pdf") as pdf:
    # 查看pdf基本信息
    print(f"总页数:{len(pdf.pages)}")  # 输出总页数
    
    # 获取第一页(索引从0开始)
    first_page = pdf.pages[0]
    
    # 查看页面属性
    print(f"页面尺寸:{first_page.width} x {first_page.height} 像素")
    print(f"页面旋转角度:{first_page.rotation}°")  # 0表示正常,90/180表示旋转
    print(f"是否包含图片:{len(first_page.images) > 0}")

说明:用with语句加载pdf可自动释放资源,避免文件占用;pages是一个列表,pdf.pages[0]表示第1页,pdf.pages[-1]表示最后一页。

2. 提取文本:保留布局与细节

pdfplumber提取文本的核心方法是extract_text(),它会按页面布局还原文本顺序,比其他库更贴近“人眼所见”。

import pdfplumber

with pdfplumber.open("example.pdf") as pdf:
    # 提取第2页文本
    page = pdf.pages[1]  # 第2页(索引1)
    text = page.extract_text()
    
    # 打印提取的文本(前500字符)
    if text:
        print("提取的文本:")
        print(text[:500] + "...")  # 只显示前500字符
    else:
        print("该页面无文本内容(可能是扫描版pdf)")

进阶:获取文本的位置与样式

如果需要更详细的信息(如文字坐标、字体、大小),可用extract_words()

with pdfplumber.open("example.pdf") as pdf:
    page = pdf.pages[0]
    # 提取页面中所有文字的详细信息(列表 of 字典)
    words = page.extract_words()
    
    # 打印前3个文字的信息
    for word in words[:3]:
        print(f"文字:{word['text']}")
        print(f"位置:x={word['x0']:.2f}, y={word['top']:.2f}(左上角)")
        print(f"大小:宽={word['width']:.2f}, 高={word['height']:.2f}")
        print(f"字体:{word.get('fontname', '未知')}, 大小={word.get('size', '未知')}\n")

用途:可用于判断标题(通常字体更大)、提取特定区域的文本(如根据坐标过滤)。

3. 提取表格:自动识别结构(核心优势)

pdfplumber最强大的功能是提取表格,extract_table()extract_tables()方法能自动识别表格边框,输出结构化的列表(每行是一个子列表),直接可用pandas转为dataframe。

示例1:提取单个表格

import pdfplumber
import pandas as pd

with pdfplumber.open("report.pdf") as pdf:
    page = pdf.pages[2]  # 假设第3页有一个表格
    
    # 提取表格(返回列表 of 列表)
    table = page.extract_table()
    
    if table:
        # 用pandas转为dataframe(方便后续处理)
        df = pd.dataframe(table[1:], columns=table[0])  # 第0行为表头
        print("提取的表格:")
        print(df.head())  # 打印前5行
        # 保存为excel
        df.to_excel("extracted_table.xlsx", index=false)
    else:
        print("未检测到表格")

示例2:提取页面中所有表格

如果一页有多个表格,用extract_tables()(注意多了个s),返回表格列表:

with pdfplumber.open("multi_tables.pdf") as pdf:
    page = pdf.pages[0]
    # 提取所有表格(返回列表 of 表格)
    all_tables = page.extract_tables()
    
    print(f"页面中共检测到 {len(all_tables)} 个表格")
    
    # 遍历每个表格并保存
    for i, table in enumerate(all_tables):
        if table:
            df = pd.dataframe(table[1:], columns=table[0])
            df.to_excel(f"table_{i+1}.xlsx", index=false)
            print(f"表格 {i+1} 已保存")

自定义表格提取参数

复杂表格(如无明显边框、合并单元格)可能需要调整参数,常用参数:

  • table_settings={"vertical_strategy": "lines", "horizontal_strategy": "lines"}:指定表格边框识别策略(lines=按线条,text=按文本间距)。
  • snakeize=true:自动将表头转为蛇形命名(如“用户id”→“user_id”)。

示例:处理无明显边框的表格:

table = page.extract_table(
    table_settings={
        "vertical_strategy": "text",  # 按文本垂直间距识别列
        "horizontal_strategy": "text"  # 按文本水平间距识别行
    }
)

4. 提取指定区域的内容

如果只需提取pdf中某块区域(如左上角的标题、右下角的签名),可通过坐标框选区域。

import pdfplumber

with pdfplumber.open("invoice.pdf") as pdf:
    page = pdf.pages[0]
    
    # 定义区域:(x0, top, x1, bottom),即左上角x、y和右下角x、y
    # 可通过pdfplumber的可视化工具查看坐标(后文介绍)
    area = (50, 50, 400, 150)  # 示例区域(需根据实际pdf调整)
    
    # 提取指定区域的文本
    region_text = page.crop(area).extract_text()
    print("指定区域的文本:")
    print(region_text)
    
    # 提取指定区域的表格(如果有的话)
    region_table = page.crop(area).extract_table()
    if region_table:
        print("指定区域的表格:")
        for row in region_table:
            print(row)

如何获取区域坐标?

推荐用pdfplumber自带的可视化工具:运行pdfplumber-cli inspect example.pdf,在浏览器中打开链接,鼠标框选区域即可显示坐标。

四、实战场景:解决实际问题

掌握基础后,我们来看几个实用场景,直接复用代码即可解决工作中的pdf处理需求。

场景1:批量提取多页pdf的文本到txt

将一个多页pdf的所有文本提取到单个txt文件,按页码分隔:

import pdfplumber

def pdf_to_txt(pdf_path, txt_path):
    """将pdf所有页面的文本提取到txt"""
    with pdfplumber.open(pdf_path) as pdf, open(txt_path, "w", encoding="utf-8") as f:
        for i, page in enumerate(pdf.pages, start=1):
            text = page.extract_text()
            if text:
                f.write(f"=== 第 {i} 页 ===\n")
                f.write(text + "\n\n")
        print(f"文本已提取到 {txt_path}")

# 用法:提取report.pdf的文本到report.txt
pdf_to_txt("report.pdf", "report.txt")

场景2:提取pdf中的所有表格并合并到excel

将pdf中所有页面的表格提取后,合并到一个excel的不同工作表:

import pdfplumber
import pandas as pd
from openpyxl import load_workbook

def extract_all_tables_to_excel(pdf_path, excel_path):
    """提取pdf中所有表格到excel的多个工作表"""
    with pdfplumber.open(pdf_path) as pdf:
        # 创建一个excel写入器
        writer = pd.excelwriter(excel_path, engine="openpyxl")
        
        table_count = 0  # 统计总表格数
        
        for page_num, page in enumerate(pdf.pages, start=1):
            tables = page.extract_tables()
            if not tables:
                continue
            
            for i, table in enumerate(tables, start=1):
                table_count += 1
                # 转换为dataframe
                try:
                    df = pd.dataframe(table[1:], columns=table[0])
                except:
                    # 处理无表头的表格
                    df = pd.dataframe(table)
                
                # 工作表名称:页面_表格序号
                sheet_name = f"页{page_num}_表{i}"
                # 写入excel(超过31字符会被截断,需处理)
                df.to_excel(writer, sheet_name=sheet_name[:31], index=false)
                print(f"已提取:{sheet_name}")
        
        writer.close()
        print(f"所有表格(共{table_count}个)已保存到 {excel_path}")

# 用法:提取所有表格到all_tables.xlsx
extract_all_tables_to_excel("multi_page_report.pdf", "all_tables.xlsx")

场景3:提取发票中的关键信息(如金额、日期)

针对格式固定的发票pdf,提取指定区域的关键信息(如发票号、金额、日期):

import pdfplumber

def extract_invoice_info(pdf_path):
    """提取发票中的关键信息"""
    with pdfplumber.open(pdf_path) as pdf:
        page = pdf.pages[0]  # 发票通常只有1页
        
        # 定义各信息的区域(需根据实际发票调整坐标)
        regions = {
            "发票号": (350, 120, 500, 140),  # x0, top, x1, bottom
            "开票日期": (350, 150, 500, 170),
            "总金额": (350, 300, 500, 320)
        }
        
        info = {}
        for key, area in regions.items():
            # 裁剪区域并提取文本
            text = page.crop(area).extract_text()
            # 清洗文本(去除空格、换行)
            if text:
                info[key] = text.replace("\n", "").strip()
            else:
                info[key] = "未找到"
        
        return info

# 用法:提取发票信息
invoice_info = extract_invoice_info("invoice.pdf")
print("发票信息:")
for key, value in invoice_info.items():
    print(f"{key}:{value}")

提示:不同发票的区域坐标不同,可先用pdfplumber-cli inspect工具获取准确坐标。

场景4:处理扫描版pdf(需结合ocr)

注意:pdfplumber只能提取**文本型pdf**(由文字组成),无法直接处理**扫描版pdf**(本质是图片)。此时需先用ocr工具(如pytesseract)将图片转为文本,再用pdfplumber处理。

示例:结合ocr提取扫描版pdf的文本:

import pdfplumber
import pytesseract
from pil import image

def ocr_scanned_pdf(pdf_path, txt_path):
    """提取扫描版pdf的文本(需安装tesseract ocr)"""
    with pdfplumber.open(pdf_path) as pdf, open(txt_path, "w", encoding="utf-8") as f:
        for i, page in enumerate(pdf.pages, start=1):
            # 将pdf页面转为图片
            img = page.to_image().original  # 获取pil image对象
            # 用ocr识别图片中的文本
            text = pytesseract.image_to_string(img, lang="chi_sim")  # 中文识别
            # 写入txt
            f.write(f"=== 第 {i} 页 ===\n")
            f.write(text + "\n\n")
        print(f"扫描版pdf文本已提取到 {txt_path}")

# 用法(需先安装tesseract并配置环境变量):
# ocr_scanned_pdf("scanned_invoice.pdf", "scanned_text.txt")

前置条件:需安装tesseract ocr引擎和pytesseract库,具体步骤参考tesseract官网

五、避坑指南:常见问题与解决方案

提取的文本乱码或缺失

  1. 原因:pdf字体编码特殊,或文本被图片覆盖。
  2. 解决:尝试用page.extract_text(x_tolerance=1, y_tolerance=1)调整 tolerance 参数;若仍乱码,可能是扫描版pdf,需结合ocr。

表格提取错乱(行列不对齐)

  1. 原因:表格无明显边框,或存在合并单元格。
  2. 解决:调整table_settings参数,如{"vertical_strategy": "text", "horizontal_strategy": "text"};或手动指定表格区域(crop后再提取)。

大文件处理缓慢或内存溢出

  1. 原因:一次性加载整个pdf占用内存大。
  2. 解决:分页处理,提取一页释放一页资源:
with pdfplumber.open("large.pdf") as pdf:
    for page in pdf.pages:
        # 处理当前页...
        text = page.extract_text()
        # 处理完后无需保留page对象

无法提取加密pdf

  1. 原因:pdf被加密(需密码才能打开)。
  2. 解决:先解密pdf(可用qpdf工具),再用pdfplumber处理:qpdf --decrypt input.pdf output.pdf

六、总结:pdf处理,选对工具事半功倍

pdfplumber凭借精准的文本和表格提取能力,成为python处理pdf的首选库之一。它的核心优势在于:

  • 对表格的提取能力远超同类库,几乎能还原excel般的结构;
  • 提供丰富的细节控制(区域提取、样式获取),灵活应对复杂场景;
  • 代码简洁易上手,无需深入了解pdf底层原理。

如果你需要处理文本型pdf(尤其是包含表格的报表、发票、合同),pdfplumber能帮你节省大量手动录入时间。对于扫描版pdf,可结合ocr工具形成完整解决方案。

以上就是python使用pdfplumber提取pdf内容的操作指南的详细内容,更多关于python pdfplumber提取pdf的资料请关注代码网其它相关文章!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com