在 Python 中解析 PDF,并不只是打开文件、把内容打印到控制台。真正的解析是从文档中提取信息——文本、表格、表单域和元数据——并将它们组织成字典、列表等 Python 数据结构。这些结构随后可以序列化为 JSON,供下游程序使用。
本教程介绍如何使用 Spire.PDF for Python 在 Python 中解析 PDF。Spire.PDF for Python 是一套独立的 Python PDF 解析库,无需依赖 Adobe Acrobat。你将学会逐页提取文本、把表格解析为行和列、读取已有的表单域值,以及获取文档元数据,并把按页提取的文本与表格结果整合为一个结构化 JSON 对象,交由下游程序处理。

快速导航
- 在 Python 中解析 PDF 意味着什么?
- 加载 PDF 并检查其内容
- 将 PDF 文本解析为结构化数据
- 将 PDF 表格解析为行和列
- 提取表单域与文档元数据
- 处理扫描版 PDF 与特殊情况
- 在 Python 工作流中使用解析后的 PDF 数据
- 总结
1. 在 Python 中解析 PDF 意味着什么?
在 Python 中解析 PDF,指的是从文档中提取所需的信息,并整理成程序能够使用的形式。具体做法取决于 PDF 的类型和任务目标:可能是按页收集文本、把表格单元格提取为行和列、读取表单域的值,或是获取文档元数据。针对不同的文档,你还可以把解析与其他技术结合起来,用于定位特定的数据字段。
在本教程中,「读取」泛指访问 PDF 内容,而「解析」侧重于把这些内容提取出来,并整理成便于下游处理的结构。在 PDF 开发中这两个词经常混用,真正的区别在于输出结果:
- 读取 PDF:让你能够访问其中的内容——页面、文本、图像——以便查看或打印文档里有什么。
- 解析 PDF:将提取出的内容组织成数据结构,以页码、行列索引或字段名作为键,使另一个程序无需人工查看就能处理这些结果。
不同的解析目标,需要采用不同的方法:
| 解析目标 | 方法 | 所在章节 |
|---|---|---|
| 文本 | PdfTextExtractor |
将 PDF 文本解析为结构化数据 |
| 表格 | PdfTableExtractor |
将 PDF 表格解析为行和列 |
| 表单域 | PdfFormWidget |
提取表单域与文档元数据 |
| 扫描页 | OCR | 处理扫描版 PDF 与特殊情况 |
本指南聚焦于解析文本、表格和表单数据。如果你需要从 PDF 中提取图片,请参考现有的使用 Python 读取 PDF 教程。
2. 加载 PDF 并检查其内容
在解析之前,需要先加载 PDF 文档,并了解它的基本结构——包含多少页、每页的尺寸是多少。
安装 Spire.PDF for Python
pip install spire.pdf
加载并检查 PDF
from spire.pdf import PdfDocument
doc = PdfDocument()
doc.LoadFromFile("sample.pdf")
print(f"页数:{doc.Pages.Count}")
for i in range(doc.Pages.Count):
page = doc.Pages.get_Item(i)
print(f"第 {i+1} 页:{page.Size.Width} x {page.Size.Height}")
doc.Close()
这段代码加载一个 PDF 文件,输出总页数,并逐页报告其宽度和高度。LoadFromFile 方法接收文件路径字符串;Pages.Count 返回页数;Pages.get_Item(i) 用于访问单个页面对象。
文档加载完成后,就可以把页面对象传给后续章节中的各类提取器。
3. 将 PDF 文本解析为结构化数据
在 Python 中解析 PDF 时,最常见的任务就是提取文本。下面的做法并没有把所有文本拼成一个长字符串,而是以页码为键,把每页的文本存入字典。这样一来,下游代码可以直接按页查找,无需拆分字符串或跟踪偏移量。
import json
from spire.pdf import PdfDocument, PdfTextExtractor, PdfTextExtractOptions
doc = PdfDocument()
doc.LoadFromFile("sample.pdf")
# 将文本解析为结构化字典:{页码: 文本}
parsed_text = {}
for i in range(doc.Pages.Count):
page = doc.Pages.get_Item(i)
extractor = PdfTextExtractor(page)
options = PdfTextExtractOptions()
options.IsExtractAllText = True
parsed_text[i + 1] = extractor.ExtractText(options)
doc.Close()
# 序列化,供下游处理
with open("parsed_text.json", "w", encoding="utf-8") as f:
json.dump(parsed_text, f, ensure_ascii=False, indent=2)
这里为每一页创建 PdfTextExtractor,并通过设置 IsExtractAllText = True 的 PdfTextExtractOptions 指示提取器获取该页的全部文本。结果保存在 parsed_text 中,这是一个以页码(从 1 开始)为键、以文本内容为值的字典。最后,该字典被序列化为 JSON。
PdfTextExtractOptions 类还提供了 IsSimpleExtraction 属性,它采用不同的换行处理方式。本教程的示例统一使用 IsExtractAllText = True,以获得更完整的文本。针对具体文档,你也可以尝试 IsSimpleExtraction,并保留输出与你内容最相符的那个选项。

需要注意,JSON 的键始终是字符串("1"、"2"),但这并不影响该字典作为下游程序输入的价值——需要时可以用 int(k) 把键转回整数。
如果你需要对文本提取进行更精细的控制——例如提取指定区域的文本、用正则表达式搜索或替换文本——请参阅文本提取教程。
4. 将 PDF 表格解析为行和列
许多 PDF 文档都包含表格数据——发票、报表、财务报表。PdfTableExtractor 类能够识别并提取 PDF 页面中的表格。它返回的表格对象可编程访问其行、列和单元格文本,并遵循表格本身的布局(包括合并单元格)。下面的代码遍历所有页面,提取找到的每一张表格,并将结果保存为字典列表。
import json
from spire.pdf import PdfDocument, PdfTableExtractor
doc = PdfDocument()
doc.LoadFromFile("sample.pdf")
extractor = PdfTableExtractor(doc)
all_tables = []
for page_idx in range(doc.Pages.Count):
tables = extractor.ExtractTable(page_idx) or []
for table in tables:
rows = table.GetRowCount()
cols = table.GetColumnCount()
table_data = []
for r in range(rows):
row = [table.GetText(r, c) for c in range(cols)]
table_data.append(row)
all_tables.append({"page": page_idx + 1, "data": table_data})
doc.Close()
# 输出结果(含空表保护)
for t in all_tables:
row_count = len(t["data"])
col_count = len(t["data"][0]) if row_count else 0
print(f"第 {t['page']} 页:{row_count} 行 x {col_count} 列")
# 序列化,供下游处理
with open("parsed_tables.json", "w", encoding="utf-8") as f:
json.dump(all_tables, f, ensure_ascii=False, indent=2)
ExtractTable 方法返回指定页索引上找到的表格对象列表。or [] 这一保护同时处理空列表和可能返回 None 的情况。对于每张表格,GetRowCount 和 GetColumnCount 给出其尺寸,GetText(row, col) 则读取指定位置的单元格内容。当某一页没有表格时,代码也能从容处理——循环体不会执行。
输出循环使用了一个显式的空表保护判断(len(t["data"][0]) if row_count else 0),避免表格行数为零时抛出 IndexError。

如果你需要把表格导出为 Excel 格式而非 JSON,请参阅 PDF 转 Excel 转换教程。
5. 提取表单域与文档元数据
PDF 表单中包含供用户填写的交互式字段——文本框、复选框、列表框。以编程方式解析这些字段,可以自动收集已填写表单中的数据。此外,你还可以提取 PDF 文档的元数据(标题、作者、主题、关键字),用于归档与检索。
解析表单域的值
from spire.pdf import (
PdfDocument,
PdfFormWidget,
PdfTextBoxFieldWidget,
)
doc = PdfDocument()
doc.LoadFromFile("form.pdf")
form = PdfFormWidget(doc.Form)
fields = {}
for i in range(form.FieldsWidget.Count):
field = form.FieldsWidget.get_Item(i)
if isinstance(field, PdfTextBoxFieldWidget):
fields[field.Name] = field.Text
print(fields)
doc.Close()
这段代码用 PdfFormWidget 包装文档的表单,然后遍历所有表单域。isinstance 判断专门筛选文本框字段——PdfTextBoxFieldWidget——并将每个字段的名称和值存入字典。

这个示例读取的是表单中已定义的文本框字段的值。关于其他字段类型(复选框、列表框、签名域)的详细说明,请参阅表单域提取教程。
解析文档元数据
from spire.pdf import PdfDocument
doc = PdfDocument()
doc.LoadFromFile("sample.pdf")
info = doc.DocumentInformation
metadata = {
"title": info.Title, "author": info.Author,
"subject": info.Subject, "keywords": info.Keywords
}
print(metadata)
doc.Close()
DocumentInformation 属性提供了访问 PDF 元数据字段的入口。每个字段都以字符串形式读取,并存入一个便于访问的字典。
6. 处理扫描版 PDF 与特殊情况
大多数 PDF 可以直接解析。少数文档需要额外的步骤或配合其他技术,下表列出这些情况并指向相应的指导内容:
| 情况 | 背景 | 建议 |
|---|---|---|
| 扫描件、纯图片页面 | 内容以图像形式存储,而非文本层 | 使用 OCR 识别文字 → OCR 教程 |
| 多栏或版式复杂的页面 | 阅读顺序取决于 PDF 内部的文本流 | 使用区域提取来定位特定区域 → 文本提取教程 |
| 含合并单元格或无边框的表格 | 单元格网格并非由可见线条绘制 | 使用带布局选项的 PDF 转 Excel → PDF 转 Excel 教程 |
| 不常见的字体编码 | 部分 PDF 以内嵌的冷门编码嵌入字体 | 选择与文档相匹配的提取选项 |
对于没有文本层的纯图片扫描 PDF,你看到的内容是以页面图像而非可提取文本的形式存储的。OCR 能够识别这些图像中的文字。完整的 OCR 实现请参见OCR 教程,此处不再重复。
当页面采用多栏或不规则的版式时,基于区域的提取让你可以按坐标定位某个区域,从而保持你所期望的阅读顺序。
7. 在 Python 工作流中使用解析后的 PDF 数据
前面几节分别产生了独立的数据结构:parsed_text(按页文本组成的字典)和 all_tables(表格数据组成的列表)。在实际使用中,往往需要一份统一的文档表示,把文本与表格按页合并在一起。
下面的代码把两个结果合并为一个结构。该示例假设你已在同一个 Python 会话中运行过前面的文本提取和表格提取示例。
import json
# 复用前面章节的 parsed_text 和 all_tables
unified = {"pages": []}
for page_num in sorted(parsed_text.keys()):
page_tables = [t["data"] for t in all_tables if t["page"] == page_num]
unified["pages"].append({
"page": page_num,
"text": parsed_text[page_num],
"tables": page_tables
})
with open("parsed_document.json", "w", encoding="utf-8") as f:
json.dump(unified, f, ensure_ascii=False, indent=2)

这份统一结构由开发者根据前面得到的文本字典和表格列表、以页码为关联来组合而成。组装完成后,提取出的数据可以转换为 pandas DataFrame 用于分析,映射到数据库字段,或发送到另一个 API 端点。需要注意,统一后的 JSON 是嵌套结构;若要将其转换为扁平的 DataFrame,需要选取特定字段或展开表格数据。
在这个工作流中,解析带来的实际收益在于:提取出的文本与表格数据被组织成一种统一的表示,下游程序可以直接使用。
8. 总结
在 Python 中解析 PDF,远不止提取文本那么简单。借助 Spire.PDF for Python,你可以把按页文本组织成字典、把表格提取为行和列,并读取已有的表单域值和文档元数据。
这些结果可以合并为统一的 JSON 结构,供下游处理使用,例如数据分析、数据库存储或与其他应用集成。具体方法取决于 PDF 的内容:纯图片的扫描页面用 OCR 处理,多栏或版式复杂的页面则可以用契合其布局的提取选项来解析。
为你的应用选择合适的提取方式,并把结果整理成便于使用的结构,就能构建出一套契合自身数据处理需求的 PDF 解析工作流。
如果需要在真实业务环境中测试 Spire.PDF for Python,可以申请临时许可证。







