Python PDF 教程:从入门到精通
在 Python 生态中,处理 PDF 文件通常不是一项单一的任务,因为 PDF 本身是一种复杂的格式,我们通常需要不同的库来处理不同的需求,

- 从 PDF 提取文本
- 从 PDF 提取图片
- 合并或拆分 PDF
- 创建新的 PDF
- 填写 PDF 表单
- 加密或解密 PDF
下面,我将介绍几个最核心、最常用的 Python PDF 库,并提供详细的教程和代码。
第一步:安装(下载)核心库
在开始之前,您需要通过 pip 安装这些库,打开您的终端或命令提示符,运行以下命令:
# 1. 用于提取文本和元数据 (推荐) pip install PyPDF2 # 2. 用于提取文本 (功能更强大,基于 C++) pip install pdfplumber # 3. 用于提取图片 pip install pdf2image # 4. 用于创建、修改、合并、拆分 PDF (功能最全面) pip install PyMuPDF # 注意:这个库的包名是 fitz,但通过 pip 安装时用 PyMuPDF pip install pymupdf # 另一种安装方式,推荐 # 5. 用于处理 PDF 表单 pip install pdfrw
使用 PyPDF2 读取和操作 PDF
PyPDF2 是一个纯 Python 库,非常适合用于基本的 PDF 操作,如合并、拆分、旋转和提取元数据。
提取文本和元数据
import PyPDF2
# 打开 PDF 文件
with open('example.pdf', 'rb') as file:
# 创建一个 PdfReader 对象
reader = PyPDF2.PdfReader(file)
# --- 获取元数据 ---
if reader.metadata:
print("--- PDF 元数据 ---")
print(f"标题: {reader.metadata.get('/Title', 'N/A')}")
print(f"作者: {reader.metadata.get('/Author', 'N/A')}")
print(f"创建者: {reader.metadata.get('/Creator', 'N/A')}")
print(f"创建日期: {reader.metadata.get('/CreationDate', 'N/A')}")
print("-" * 20)
# --- 获取页面总数 ---
num_pages = len(reader.pages)
print(f"总页数: {num_pages}")
print("-" * 20)
# --- 提取特定页面的文本 ---
# 注意:PyPDF2 在提取格式化文本方面能力有限
page = reader.pages[0] # 获取第一页
text = page.extract_text()
print("--- 第一页文本 ---")
print(text)
print("-" * 20)
合并 PDF 文件
import PyPDF2
def merge_pdfs(pdf_list, output_filename):
"""合并多个PDF文件"""
merger = PyPDF2.PdfMerger()
for pdf in pdf_list:
merger.append(pdf)
merger.write(output_filename)
merger.close()
print(f"PDF已成功合并为 {output_filename}")
# 示例用法
pdfs_to_merge = ['file1.pdf', 'file2.pdf']
merge_pdfs(pdfs_to_merge, 'merged_document.pdf')
拆分 PDF 文件
import PyPDF2
def split_pdf(input_pdf, output_prefix):
"""拆分PDF的每一页为单独的文件"""
with open(input_pdf, 'rb') as file:
reader = PyPDF2.PdfReader(file)
for page_num in range(len(reader.pages)):
writer = PyPDF2.PdfWriter()
writer.add_page(reader.pages[page_num])
output_filename = f"{output_prefix}_page_{page_num + 1}.pdf"
with open(output_filename, 'wb') as output_file:
writer.write(output_file)
print(f"已创建: {output_filename}")
# 示例用法
split_pdf('example.pdf', 'split_page')
使用 pdfplumber 提取更精确的文本
pdfplumber 在 PyPDF2 的基础上进行了封装,特别擅长提取带有复杂布局的文本,并且可以获取每行文本的位置信息。

import pdfplumber
with pdfplumber.open('example.pdf') as pdf:
# 遍历每一页
for i, page in enumerate(pdf.pages):
print(f"--- 第 {i+1} 页 ---")
# extract_text() 方法通常比 PyPDF2 更准确
text = page.extract_text()
print(text)
# extract_words() 可以获取每个单词及其位置信息
words = page.extract_words()
print("\n--- 单词及其位置 ---")
for word in words[:5]: # 只打印前5个单词作为示例
print(word)
# extract_tables() 可以提取表格
tables = page.extract_tables()
if tables:
print("\n--- 提取到的表格 ---")
for table in tables:
for row in table:
print(row)
使用 PyMuPDF (fitz) 进行高级操作
PyMuPDF (也称为 fitz) 是一个功能极其强大的库,速度飞快,不仅能处理文本和图片,还能渲染 PDF 页面为图像,是处理 PDF 的“瑞士军刀”。
提取文本和图片
import fitz # PyMuPDF
doc = fitz.open('example.pdf')
# --- 提取所有文本 ---
print("--- 全文文本 ---")
text = ""
for page in doc:
text += page.get_text()
print(text)
print("-" * 20)
# --- 提取图片 ---
print("--- 提取图片 ---")
image_count = 0
for page_index in range(len(doc)):
page = doc[page_index]
image_list = page.get_images()
if image_list:
print(f"在第 {page_index + 1} 页找到 {len(image_list)} 张图片")
for image_index, img in enumerate(image_list):
xref = img[0]
base_image = doc.extract_image(xref)
image_bytes = base_image["image"]
# 保存图片
image_filename = f"image_page{page_index+1}_{image_index+1}.png"
with open(image_filename, "wb") as f:
f.write(image_bytes)
print(f"已保存图片: {image_filename}")
image_count += 1
doc.close()
print(f"总共提取了 {image_count} 张图片。")
将 PDF 页面转换为图片
import fitz
import io
from PIL import Image
doc = fitz.open('example.pdf')
page = doc.load_page(0) # 加载第一页
# 将页面渲染为图像 (pix 是一个像素对象)
pix = page.get_pixmap(dpi=300) # dpi 可以调整图片质量
# 将像素数据保存为图片文件
pix.save("page_as_image.png")
doc.close()
print("PDF页面已成功转换为图片 page_as_image.png")
处理 PDF 表单 (使用 pdfrw)
pdfrw 可以用来读取和写入 PDF 表单数据。
读取表单数据
from pdfrw import PdfReader
# 读取 PDF
pdf = PdfReader('form.pdf')
# 获取表单字段
if pdf.Root.AcroForm:
fields = pdf.Root.AcroForm.fields
print("--- 表单字段 ---")
for field in fields:
# 字段名称和值
field_name = field.T
field_value = field.V if hasattr(field, 'V') else 'N/A'
print(f"字段: {field_name}, 值: {field_value}")
else:
print("该PDF没有可交互的表单。")
填写表单并保存为新文件
from pdfrw import PdfReader, PdfWriter, IndirectPdfDict
# 读取模板 PDF
template_pdf = PdfReader('form.pdf')
output_pdf = PdfWriter()
# 假设我们要填写的字段名为 'name' 和 'email'
data_dict = {
'name': '张三',
'email': 'zhangsan@example.com'
}
# 遍历页面并更新表单字段
for page in template_pdf.pages:
if page.Parent.AcroForm:
# 更新字段值
for field in page.Parent.AcroForm.fields:
if field.T in data_dict:
field.V = IndirectPdfDict(data_dict[field.T])
output_pdf.addpage(page)
# 写入新的 PDF 文件
output_pdf.write('filled_form.pdf')
print("表单已填写并保存为 filled_form.pdf")
总结与推荐
| 库名称 | 主要用途 | 优点 | 缺点 |
|---|---|---|---|
| PyPDF2 | 读取元数据、合并、拆分、旋转 | 纯Python,简单易用,轻量级 | 提取文本能力弱,不支持修改内容 |
| pdfplumber | 精确提取文本和表格 | 文本提取准确,能获取位置信息,表格识别能力强 | 功能不如 PyMuPDF 全面 |
| PyMuPDF (fitz) | 全能型工具 | 速度极快,功能最全面(文本、图片、渲染、修改、表单等) | API 相对复杂,依赖系统库 |
| pdfrw | 处理 PDF 表单 | 操作表单简单直接 | 功能较少,不适合复杂操作 |
如何选择?
- 如果你只是想快速合并或拆分 PDF:使用
PyPDF2。 - 如果你需要从 PDF 中精确地提取文本,特别是表格:使用
pdfplumber。 - 如果你需要做任何复杂的事情,比如提取图片、渲染页面、修改 PDF 内容或需要最高性能:强烈推荐使用
PyMuPDF。 - 如果你的任务只是填写 PDF 表单:使用
pdfrw。
希望这份详细的教程能帮助您开始在 Python 中处理 PDF 文件!

