前言¶
从 PDF 里拿东西,常见的坑是:pdftotext 抽出的表格变成一行没分隔符的字符串;PyPDF2 只给纯文本,丢掉了行列结构;好不容易抽出表格,却不知道某个单元格为什么串行。要拿到字符级的坐标、线条、矩形,再自己判断哪几个字符组成一个表格单元格,用通用文本抽取工具基本做不到。
下面介绍的 Skill 是 pdfplumber Python PDF 文本和表格提取库,把 pdfplumber 这个库封装成可调用的 Agent Skill,专门解决「从 PDF 里拿结构化信息」这件事。
这是什么¶
一句话定位:pdfplumber 是一个 Python 库,用于从 PDF 中提取详细信息——文本、表格、线条、矩形和曲线——并支持可视化调试。
- 上游项目:
jsvine/pdfplumber,基于pdfminer.six构建 - Skill 出品:SkillHub 上的社区 Skill,坐标
@user_3c6cb52e/pdfplumber-python-pdf-text-table-extraction,发布者user_3c6cb52e,来源标记为community - 版本:1.0.0
- 分类:
office-efficiency - 标签:
requires_api_key=false,即不需要额外申请 API Key
它解决的问题是:在机器生成的 PDF 上,把版面对象还原成可编程的数据结构,尤其是结构化表格。
核心功能¶
经核对上游资料,已确认的能力如下。
1、文本提取。Page.extract_text() 抽取纯文本,extract_text(layout=True) 保留版面布局,后者在 CLI 的 --format text 里被使用。
2、表格提取。page.extract_tables() 提取结构化表格,返回嵌套列表;配套 page.find_tables() 用于定位表格边界框,便于进一步裁剪或校验。这是 pdfplumber 相对其他库的主要优势点。
3、字符级与图形级对象。每页暴露 .chars、.lines、.rects、.curves、.images 列表,每个元素是字典,带 x0、top、x1、bottom、text 等字段,可直接做位置筛选和排序。
4、版面裁剪与过滤。.crop()、.within_bbox()、.outside_bbox() 按边界框裁剪页面,.filter() 用自定义函数过滤对象。边界框是 4 元组 (x0, top, x1, bottom)。
5、可视化调试。page.debug_tablefinder() 会把表格检测的边界框画成图片,用来排查「为什么这个表格没被识别出来」。
6、表单域值提取。可读取 PDF AcroForm 表单的字段名与值。
7、CLI。命令行工具支持 csv、json、text 三种输出格式,可指定页码范围和对象类型。
安装与启用¶
上游库安装¶
上游库通过 pip 安装:
pip install pdfplumber
上游仓库当前在 Python 3.10、3.11、3.12、3.13、3.14 上有测试通过记录。早期版本的中文文档标注的是 Python 3.8–3.11,与当前说明不一致,以仓库当前的测试矩阵为准。
CLI 安装¶
命令行工具随 pdfplumber[cli] 一并安装:
pip install "pdfplumber[cli]"
Skill 启用¶
SkillHub 页面坐标:
@user_3c6cb52e/pdfplumber-python-pdf-text-table-extraction
Skill 版本 1.0.0,来源 community,标签 requires_api_key=false。该 Skill 基于通用 SKILL.md 格式,因此在任何支持该格式的 Agent 里,只要把 Skill 目录放进宿主项目对应的位置即可被加载。
需要说明的是:本次抓取 SkillHub 页面未能成功,上列坐标、版本、分类、标签取自预先抓取的资料,该资料同时记录评分 100000、下载 1191、安装 0。任务描述里给出的评分 99742、下载 1161 与资料不一致,因页面无法二次核对,本文不采用这两个数字。
另外,资料没有给出针对 Cursor、Codex CLI、Claude Code 各自的安装命令差异,也没有给出 Skill 目录在宿主项目中的具体路径。这部分信息没有在已抓取资料中出现,本文不做推断。
CLI 参数¶
CLI 的可用参数如下:
pdfplumber < input.pdf > output.csv
| 参数 | 说明 |
|---|---|
--format [format] |
csv、json 或 text。csv 和 json 返回每个对象的详细信息,json 额外包含 PDF 级和页面级元数据及字典嵌套属性;text 返回 Page.extract_text(layout=True) 的纯文本。 |
--pages [list of pages] |
空格分隔的 1 起始页码或区间,如 1, 11-15。 |
--types [list of object types] |
可选 char、rect、line、curve、image、annot 等,默认全部。 |
--laparams |
JSON 字符串,传给 pdfplumber.open(..., laparams=...),如 '{"detect_vertical": true}'。 |
--precision [integer] |
浮点数保留的小数位数,默认不舍入。 |
典型用法¶
命令行:导出整份 PDF 的对象信息¶
curl "https://raw.githubusercontent.com/jsvine/pdfplumber/stable/examples/pdfs/background-checks.pdf" > background-checks.pdf
pdfplumber background-checks.pdf > background-checks.csv
输出是一份 CSV,包含 PDF 中每个字符、线条和矩形的信息。换 --format json 则输出更完整的嵌套结构。
Python:打开 PDF 并读取首页第一个字符¶
import pdfplumber
with pdfplumber.open("path/to/file.pdf") as pdf:
first_page = pdf.pages[0]
print(first_page.chars[0])
pdfplumber.open(x) 的 x 可以是文件路径、已加载为字节的文件对象,或类文件对象。
Python:加载加密 PDF¶
pdfplumber.open("file.pdf", password="test")
Python:传入布局分析参数¶
pdfplumber.open("file.pdf", laparams={"line_overlap": 0.7})
laparams 直接作用于 pdfminer.six 的布局引擎。
Python:提取表格¶
import pdfplumber
with pdfplumber.open("report.pdf") as pdf:
for page in pdf.pages:
for table in page.extract_tables():
print(table)
extract_tables() 返回嵌套列表,外层是表格,内层是一行,元素是单元格文本。需要定位表格在页面上的位置时,用 page.find_tables(),它返回的对象带 .bbox。
Python:调试表格检测¶
page.debug_tablefinder()
这个方法把检测到的边界框渲染成图片输出,用来判断表格的行线、列线是否被正确识别。
Python:裁剪页面¶
page.crop((x0, top, x1, bottom))
裁剪框内至少部分落入的对象会被保留,超出部分被切片。只想要完全落在框内的对象时用 page.within_bbox(...),只想要完全在框外的用 page.outside_bbox(...)。
适用场景与注意¶
适合的场景:
1、机器生成的 PDF,即由排版软件、报表系统、PDF 生成库输出的文件,文本是真实文本层而非图像。
2、需要把表格还原成行列结构,再转成 CSV、DataFrame 或入库的场景。
3、需要按坐标定位、裁剪、过滤特定区域的场景,比如只取页面右上角的区域。
4、需要排查抽取结果为什么错的场景,可视化调试比反复打印坐标快。
需要注意的限制:
1、扫描件 PDF 不适用。文档明确说明「用于电脑生成的 PDF 上效果最好,不支持扫描的 PDF」。扫描件需要先做 OCR。
2、表格检测依赖页面上的线条或字符对齐。如果原 PDF 的表格没有画线、字符也没有形成清晰的列对齐,find_tables() 可能检测不到或切错列,此时需要调整策略或用 laparams。
3、大 PDF 的内存占用。Page 对象默认缓存布局和对象信息以避免重复解析,处理大文件时缓存可能占用较多内存,需要时调用 page.close() 释放。
4、元数据解析默认宽松。无效元数据值默认只作为警告;如果希望解析失败就抛异常,传入 strict_metadata=True。
5、坐标系以 PDF 页面左上角为原点,top 是距顶部的距离,不是传统的 y 坐标,做区间判断时注意。
结尾¶
pdfplumber 的价值在于把 PDF 从「一个文本流」变成「一组带坐标的对象」,从而让文本抽取、表格还原、区域裁剪、结果调试都变成可编程的步骤。对于机器生成的 PDF,尤其是需要结构化表格的场景,它是目前 Python 生态里实现比较完整的一个选择。
Skill 地址:https://www.skillhub.cn/skills/user_3c6cb52e/pdfplumber-python-pdf-text-table-extraction
上游项目:https://github.com/jsvine/pdfplumber