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

作者:

文章目录
  • 处理PDF文件时,你是否遇到过这些难题:想复制表格却格式错乱?提取文本时段落被拆得支离破碎?手动录入PDF数据效率低下还易出错?如果你用过PyPDF2、pdfminer等库,可能会发现它们在处理复杂布局(尤其是表格)时力不从心。 而 pdfplumber 的出现,完美解决了这些痛点。它是一个专注于PDF内容提取的Python库,以“精准还原布局”为核心优势,能轻松提取文本、表格,甚至获取文字的位置、字体等细节信息。本文将从基础用法到实战场景,全方位讲解pdfplumber的使用,帮你彻底告别PDF处理的繁琐。
  • 在众多PDF处理库中,pdfplumber的核心竞争力在于: 表格提取精准:自动识别表格边框、合并单元格,提取结果保留表格结构(类似Excel),远超PyPDF2等库的“纯文本拼接”。 文本提取智能:按页面布局还原文本顺序,避免段落被无序拆分,还能获取文字的坐标、字体、大小等元数据。 操作简单直观:API设计简洁,几行代码即可完成提取,无需深入了解PDF底层格式。 支持细节控制:可指定提取区域(如只提取某页的某块内容)、过滤无效信息,灵活应对复杂PDF。 适合场景:数据分析师提取PDF报表、开发者批量处理合同文本、研究者抓取文献内容等。
  • pdfplumber是纯Python库,安装无需依赖复杂的系统工具,直接用pip即可: pip install pdfplumber 验证安装是否成功: import pdfplumber print(pdfplumber.__version__) # 输出版本号(如 0.9.0)即成功
  • pdfplumber的核心流程是:**加载PDF文件→获取页面→提取内容(文本/表格)**。我们从最基础的操作开始,逐步掌握核心功能。
  • 掌握基础后,我们来看几个实用场景,直接复用代码即可解决工作中的PDF处理需求。
  • 提取的文本乱码或缺失 原因:PDF字体编码特殊,或文本被图片覆盖。 解决:尝试用page.extract_text(x_tolerance=1, y_tolerance=1)调整 tolerance 参数;若仍乱码,可能是扫描版PDF,需结合OCR。 表格提取错乱(行列不对齐) 原因:表格无明显边框,或存在合并单元格。 解决:调整table_settings参数,如{"vertical_strategy": "text", "horizontal_strategy": "text"};或手动指定表格区域(crop后再提取)。 大文件处理缓慢或内存溢出 原因:一次性加载整个PDF占用内存大。 解决:分页处理,提取一页释放一页资源: with pdfplumber.open(“large.pdf”) as pdf: for page in pdf.pages: # 处理当前页… text = page.extract_text() # 处理完后无需保留page对象 无法提取加密PDF 原因:PDF被加密(需密码才能打开)。 解决:先解密PDF(可用qpdf工具),再用pdfplumber处理:qpdf –decrypt input.pdf output.pdf。
  • pdfplumber凭借精准的文本和表格提取能力,成为Python处理PDF的首选库之一。它的核心优势在于: 对表格的提取能力远超同类库,几乎能还原Excel般的结构; 提供丰富的细节控制(区域提取、样式获取),灵活应对复杂场景; 代码简洁易上手,无需深入了解PDF底层原理。 如果你需要处理文本型PDF(尤其是包含表格的报表、发票、合同),pdfplumber能帮你节省大量手动录入时间。对于扫描版PDF,可结合OCR工具形成完整解决方案。 以上就是Python使用PDFPlumber提取PDF内容的操作指南的详细内容,更多关于Python PDFPlumber提取PDF的资料请关注风君子博客其它相关文章! 您可能感兴趣的文章: 深入探索Python如何利用pdfplumber从PDF中提取信息到实际项目应用 python利用pdfplumber进行pdf文档解析提取 详解Python如何利用pdfplumber提取PDF中的表格 Python利用pdfplumber提取PDF文档中的表格数据并导出 Python利用pdfplumber库提取pdf中表格数据
  • 目录
    • 引言
    • 一、为什么选择pdfplumber?
    • 二、环境准备:1分钟安装
    • 三、基础用法:从加载PDF到提取内容
      • 1. 加载PDF并查看页面信息
      • 2. 提取文本:保留布局与细节
      • 3. 提取表格:自动识别结构(核心优势)
        • 示例1:提取单个表格
        • 示例2:提取页面中所有表格
        • 自定义表格提取参数
      • 4. 提取指定区域的内容
      • 四、实战场景:解决实际问题
        • 场景1:批量提取多页PDF的文本到TXT
          • 场景2:提取PDF中的所有表格并合并到Excel
            • 场景3:提取发票中的关键信息(如金额、日期)
              • 场景4:处理扫描版PDF(需结合OCR)
              • 五、避坑指南:常见问题与解决方案
                • 六、总结:PDF处理,选对工具事半功倍

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

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

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

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

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

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

                  pip install pdfplumber

                  验证安装是否成功:

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

                  pdfplumber的核心流程是:**加载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]表示最后一页。

                  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")

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

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

                  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("未检测到表格")

                  如果一页有多个表格,用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"  # 按文本水平间距识别行
                      }
                  )

                  如果只需提取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处理需求。

                  将一个多页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 + "nn")
                          print(f"文本已提取到 {txt_path}")
                  
                  # 用法:提取report.pdf的文本到report.txt
                  pdf_to_txt("report.pdf", "report.txt")

                  将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")

                  针对格式固定的发票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工具获取准确坐标。

                  注意: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 + "nn")
                          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

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

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

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

                  以上就是Python使用PDFPlumber提取PDF内容的操作指南的详细内容,更多关于Python PDFPlumber提取PDF的资料请关注风君子博客其它相关文章!

                  您可能感兴趣的文章:

                  • 深入探索Python如何利用pdfplumber从PDF中提取信息到实际项目应用
                  • python利用pdfplumber进行pdf文档解析提取
                  • 详解Python如何利用pdfplumber提取PDF中的表格
                  • Python利用pdfplumber提取PDF文档中的表格数据并导出
                  • Python利用pdfplumber库提取pdf中表格数据

                  站内搜索