pdfplumber
解析 PDF 文件,获取相关的文本字符、矩形和线条的详细信息。 额外功能:表格提取和可视化调试。
用于电脑生成的 PDF 上效果最好,不支持扫描的 PDF,基于pdfminer.six实现.
当前版本 测试用例 已经在 Python 3.8, 3.9, 3.10, 3.11 验证通过.
反馈 BUG 或提交功能, 请 提交 issue. 有疑问 或提交需要协助的特殊 PDF 文件, 请 进入讨论区.
👋 本项目维护人员提供 PDF 数据提取服务. 询价可联系 Jeremy (针对任何项目) 或 Samkit (针对表格提取).
目录
安装
1 pip install pdfplumber
命令行
基础示例
12 curl "https://raw.githubusercontent.com/jsvine/pdfplumber/stable/examples/pdfs/background-checks.pdf" > background-checks.pdfpdfplumber < background-checks.pdf > background-checks.csv
输出将是一个 CSV,包含 PDF 中每个字符、行和矩形的信息。
配置项
| 参数 | 说明 |
|---|---|
--format [输出格式] |
csv 或 json. json 返回信息包括 PDF 文件级和页面级元数据,以及字典嵌套属性。 |
--pages [页码] |
1-页面索引或页面范围. 举例: 1, 11-15, 指定的页面范围: 1, 11, 12, 13, 14, 15. |
--types [提取对象类型列表] |
可选值: char, rect, line, curve, image, annot等,默认全部提取 |
--laparams |
json 格式字符串 (例: '{"detect_vertical": true}') PDF 打开的传参 pdfplumber.open(..., laparams=...). |
--precision [整数] |
浮点数四舍五入的小数位数。默认为无舍入。 |
Python 库
基础示例
12345 import pdfplumber with pdfplumber.open("path/to/file.pdf") as pdf: first_page = pdf.pages[0] print(first_page.chars[0])
加载 PDF
调用pdfplumber.open(x)加载 PDF, 其中x可以有以下几种格式:
-
PDF 文件路径
-
文件对象, 以字节流形式加载
-
类文件对象, 以字节流形式加载
open方法加载文件后返回一个 pdfplumber.PDF 实例.
传入 password 参数用于加载已加密的 PDF 文件, 例: pdfplumber.open("file.pdf", password = "test").
传入 laparams 参数可以使用pdfminer.six的布局引擎用于布局分析, 例: pdfplumber.open("file.pdf", laparams = { "line_overlap": 0.7 }).
Invalid metadata values are treated as a warning by default. If that is not intended, pass strict_metadata=True to the open method and pdfplumber.open will raise an exception if it is unable to parse the metadata.
默认情况下,无效元数据值只是被视为警告。如果设置strict_metadata=True。当加载 PDF 后无法分析元数据,将抛出异常。
pdfplumber.PDF 类
pdfplumber.PDF 类代表一个 PDF 文件,主要有以下两个属性:
| 属性 | 说明 |
|---|---|
.metadata |
元数据键/值对字典,摘自 PDF 的“信息”。通常包括“CreationDate”(创建日期)、“ModDate”(修改日期)、“Producer”(创建者)等。 |
.pages |
包含pdfplumber.Page(页实例)的列表。 |
… 包含以下方法:
| 方法 | 说明 |
|---|---|
.close() |
调用此方**在每个页面上调用 Page.close(),同时也会关闭文件流(除非文件流是外部的,即已经打开并直接传递给 pdfplumber)。 |
pdfplumber.Page 类
pdfplumber.Page是pdfplumber核心. 大部分的操作都是围绕此类进行.主要包含以下属性:
| 属性 | 说明 |
|---|---|
.page_number |
页码, 1第一页, 2第二页, 以此类推. |
.width |
页面宽. |
.height |
页面高. |
.objects / .chars / .lines / .rects / .curves / .images |
这些属性中的每一个都是一个列表,每个列表都为嵌入在页面上的每个此类对象包含一个字典。有关详细信息,请参见 “Objects”. |
… pdfplumber.Page的主要方法:
| 方法 | 说明 |
|---|---|
.crop(bounding_box, relative=False, strict=True) |
返回裁剪边界框中的页面内容,边界框应表示为 4 元组,值为 (x0, top, x1, bottom)。裁剪的页面保留至少部分位于边界框内的对象。如果对象仅部分落在长方体中,则将剖切其被边界框包含的部分。如果relative=True,则边界框计算为距页面左上角的偏移量,而不是绝对位置。 (参考 Issue #245 给出的直观示例和说明.) 当strict=True (默认值), 裁剪框必须在页面边界内部. |
.within_bbox(bounding_box, relative=False, strict=True) |
类似.crop,但仅保留完全落在边界框内的对象。 |
.outside_bbox(bounding_box, relative=False, strict=True) |
类似.crop 和 .within_bbox, 仅保留边界框外部的对象. |
.filter(test_function) |
过滤对象.objects,仅提取当过滤函数test_function(obj)返回True的对象. |
… 也包含了以下方法:
| 方法 | 描述 |
|---|---|
.close() |
默认情况下,"Page"对象会缓存其布局和对象信息,以避免重新处理。不过,在解析大型 PDF 文件时,这些缓存属性可能会占用大量内存。您可以使用此方法刷新缓存并释放内存。 |
更多方法说明请看以下章节:
对象
pdfplumber.PDF 和 pdfplumber.Page实例均提供各种类型的对象, 对象来自 pdfminer.sixPDF 解析。以下属性分别返回匹配对象的 Python 列表:
.chars, 代表单个文本字符..lines, 代表一条一维线..rects, 代表单个二维矩形..curves, 代表一序列pdfminer.six无法识别成线或矩形的连接点,..images, 代表图像..annots, 代表一个 PDF 批注 (详见第 8.4 节 官方 PDF 规范).hyperlinks, 代表链接注释Link包含URI属性
以上每个对象都是字典形式,其包含以下属性:
char 属性
| 属性 | 说明 |
|---|---|
page_number |
找到此字符的页码。 |
text |
文本内容 例: “z”, 或 “Z” 或 " ". |
fontname |
字体 |
size |
字号 |
adv |
等于文本宽度字体大小比例因子。 |
upright |
是否垂直 |
height |
文本高度 |
width |
文本高度 |
x0 |
其左侧与页面左侧的距离。 |
x1 |
其右侧与页面左侧的距离。 |
y0 |
其下侧与页面底部的距离。 |
y1 |
其上侧与页面底部的距离。 |
top |
其上侧与页面顶部的距离。 |
bottom |
其下侧与页面顶部的距离。 |
doctop |
其顶部与文档顶部的距离。 |
matrix |
其“变换矩阵”。(详见下文) |
mcid |
如果有此 标记内容 则获取段落 ID (否则为 None). 实验属性 |
tag |
如果有此 标记内容 则获取段落 ID (否则为 None). 实验属性 |
ncs |
TKTK |
stroking_pattern |
TKTK |
non_stroking_pattern |
TKTK |
stroking_color |
字符轮廓颜色 (i.e., stroke). 详情查看 docs/colors.md . |
non_stroking_color |
字符填充颜色. 详情查看 docs/colors.md . |
object_type |
对象类型:“char” |
备注: 文本变换矩阵(matrix)说明请参见章节 4.2.2PDF 参考 (第 6 版). 矩阵控制角色的缩放、倾斜和位置平移。旋转是缩放和倾斜的组合,但在大多数情况下可以认为等于 x 轴倾斜。 pdfplumber.ctm子模块定义了一个类 CTM,该类可以帮助进行这些计算。例如:
1234 from pdfplumber.ctm import CTMmy_char = pdf.pages[0].chars[3]my_char_ctm = CTM(*my_char["matrix"])my_char_rotation = my_char_ctm.skew_x
line 属性
| 属性 | 说明 |
|---|---|
page_number |
其所在的页码 |
height |
高度 |
width |
宽度 |
x0 |
其左侧与页面左侧的距离。 |
x1 |
其右侧与页面左侧的距离。 |
y0 |
其下侧与页面底部的距离。 |
y1 |
其上侧与页面底部的距离。 |
top |
其上侧与页面顶部的距离。 |
bottom |
其下侧与页面顶部的距离。 |
doctop |
其顶部与文档顶部的距离。 |
linewidth |
线粗 |
stroking_color |
线段轮廓颜色. 详情查看 docs/colors.md . |
non_stroking_color |
线段填充颜色. 详情查看 docs/colors.md . |
mcid |
如果有此 标记内容 则获取段落 ID (否则为 None). 实验属性 |
tag |
如果有此 标记内容 则获取段落 ID (否则为 None). 实验属性 |
object_type |
对象类型:“line” |
rect 属性
| 属性 | 说明 |
|---|---|
page_number |
其所在的页码 |
height |
高度 |
width |
宽度 |
x0 |
其左侧与页面左侧的距离。 |
x1 |
其右侧与页面左侧的距离。 |
y0 |
其下侧与页面底部的距离。 |
y1 |
其上侧与页面底部的距离。 |
top |
其上侧与页面顶部的距离。 |
bottom |
其下侧与页面顶部的距离。 |
doctop |
其顶部与文档顶部的距离。 |
linewidth |
线粗 |
stroking_color |
矩形边框轮廓颜色. 详情查看 docs/colors.md . |
non_stroking_color |
矩形填充颜色. 详情查看 docs/colors.md . |
mcid |
如果有此 标记内容 则获取段落 ID (否则为 None). 实验属性 |
tag |
如果有此 标记内容 则获取段落 ID (否则为 None). 实验属性 |
object_type |
对象类型:“rect” |
curve 属性
| 属性 | 说明 |
|---|---|
page_number |
其所在的页码 |
points |
Points — 描述曲线的点列表包含 (x, top) 元组 |
height |
曲线边界框的高度。 |
width |
曲线边界框的宽度。 |
x0 |
曲线最左侧点与页面左侧的距离。 |
x1 |
曲线最右侧点与页面左侧的距离。 |
y0 |
曲线最低点到页面底部的距离。 |
y1 |
曲线最高点到页面底部的距离。 |
top |
曲线最高点到页面顶部的距离。 |
bottom |
曲线最低点到页面底部的距离。 |
doctop |
曲线最高点到文档顶部的距离。 |
linewidth |
线粗 |
fill |
是否填充曲线路径定义的形状. |
stroking_color |
曲线轮廓颜色. 详情查看 docs/colors.md . |
non_stroking_color |
曲线填充颜色. 详情查看 docs/colors.md . |
mcid |
如果有此 标记内容 则获取段落 ID (否则为 None). 实验属性 |
tag |
如果有此 标记内容 则获取段落 ID (否则为 None). 实验属性 |
object_type |
对象类型:“curve” |
衍生属性
此外, pdfplumber.PDF 和 pdfplumber.Page还提供以下两个对象:
.rect_edges (将每个矩形分解为四条线)
.curve_edges (与curve对象相同)
.edges(将 .rect_edges,.curve_edges与.lines组合在一起)。
image 属性
[待完善.]
获取pdfminer.six高级布局对象
加载 PDF( pdfplumber.open(...))时通过传参laparams打开 PDF 后,每个页面对象将包含 pdfminer.six高级布局对象, 例如: "textboxhorizontal".
可视化调试
pdfplumber的调试工具可以辅助了解 PDF 文档结构,利用工具可以导出对象信息.
输出页面图像对象 PageImage
使用 my_page.to_image()获取页面(包括裁剪页面)的图像对象 PageImage .设置分辨率resolution={integer}, 默认分辨率:72 例:
使用 my_page.to_image()获取页面(包括裁剪页面)的图像对象 PageImage. 以下参数可以设置:
resolution: 图片分辨率resolution={integer}, 默认分辨率:72. 类型:int.width: 图片宽度(像素).默认:未设置, 取决于resolution. 类型:int.height: 图片高度(像素).默认:未设置, 取决于resolution. 类型:int.resolution: The desired number pixels per inch. Default:72. 类型:int.antialias: 创建图像时是否使用抗锯齿(antialiasing)。设置为True可以生成更平滑的文本和图形,但文件大小会变大。默认情况下是False. 类型:bool.force_mediabox: 使用页面的.mediabox尺寸,而不是.cropbox尺寸。默认:False。类型:bool。
示例:
1 im = my_pdf.pages[0].to_image(resolution=150)
使用脚本或交互环境时,im.show()将使用本地图片浏览器查看图片, PageImage 对象也可以很好地与 Jupyter 配合使用;它们会自动渲染为单元格输出。例如:

备注: .to_image(...) 原型是 Page.crop(...)/CroppedPage 实例, 但是其无法使用 Page.filter(...)/FilteredPage 实例进行改变.
PageImage 基础方法
| 方法 | 说明 |
|---|---|
im.reset() |
重置,清除已绘制的所有内容。 |
im.copy() |
将图像复制到新的“PageImage”对象。 |
im.show() |
使用本地图片查看器浏览图片 |
im.save(path_or_fileobject, format="PNG") |
保存已标记的图片 |
im.save(path_or_fileobject, format="PNG", quantize=True, colors=256, bits=8) |
将带有注释的图像保存为 PNG 文件。默认参数会将图像量化为一个包含 256 种颜色的调色板,并以 8 位色深保存 PNG 文件。如果想禁用量化,可以传递quantize=False参数;如果想调整颜色调色板的大小,可以传递colors=N参数,其中 N 表示颜色的数量 |
绘制方法
你可以传递坐标或pdfplumberPDF 对象 (例: char, line, rect)进行绘图.
| 单对象绘制 | 批量绘制 | 说明 |
|---|---|---|
im.draw_line(line, stroke={color}, stroke_width=1) |
im.draw_lines(list_of_lines, **kwargs) |
绘制线条根据line, curve, 或起止点坐标元组(例: ((x, y), (x, y))). |
im.draw_vline(location, stroke={color}, stroke_width=1) |
im.draw_vlines(list_of_locations, **kwargs) |
在location处 x 坐标处绘制一条垂直线 |
im.draw_hline(location, stroke={color}, stroke_width=1) |
im.draw_hlines(list_of_locations, **kwargs) |
在location处 y 坐标处绘制一条水平线 |
im.draw_rect(bbox_or_obj, fill={color}, stroke={color}, stroke_width=1) |
im.draw_rects(list_of_rects, **kwargs) |
绘制矩形rect, char, 等, 或 4 坐标元组边界框. |
im.draw_circle(center_or_obj, radius=5, fill={color}, stroke={color}) |
im.draw_circles(list_of_circles, **kwargs) |
以(x, y)为圆心画圆 char, rect, 等. |
备注:以上绘图方法是基于 Pillow 实现的 ImageDraw methods, 但是为了与 SVG 的一致性,调整了fill/stroke/stroke_width参数命名.
直观调试表格查找器
im.debug_tablefinder(table_settings={}) 将返回一个页面图像版本,并叠加检测到的线条(红色)、交叉点(圆形)和表格(浅蓝色)。
提取文本
pdfplumber 可以从页面提取文本 (包括裁剪的或者衍生的页面). 它也尽量尝试保持文本布局, 尽可能的识别单词的坐标及查询条件. Page对象可以使用以下方法进行文本提取:
| 方法 | 说明 |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------- |
| .extract_text(x_tolerance=3, x_tolerance_ratio=None, y_tolerance=3, layout=False, x_density=7.25, y_density=13, **kwargs) | 提取页面字符串.
当
layout=False: 如果一个字符的x1与下一个字符的x0之间的差大于x_tolerance,则添加空格。(如果x_tolerance_ratio不是None,提取器将使用等于x_tolerance_ratio * previous_character["size"]的动态x_tolerance)。如果一个字符的doctop与下一个字符的doctop之间的差大于y_tolerance,则添加换行符。当
layout=True(实验性功能): 尝试模拟页面上文本的结构布局,使用x_density和y_density来确定每个"点"(PDF 的单位)所需的最小字符数/换行符数。所有剩余的**kwargs参数会传递给.extract_words(...)(见下文),这是计算布局的第一步
|
.extract_text_simple(x_tolerance=3, y_tolerance=3) | .extract_text(...)的加速版,使用了较为简单的判断逻辑,获取的内容可能没那么精确. ||
.extract_words(x_tolerance=3, x_tolerance_ratio=None, y_tolerance=3, keep_blank_chars=False, use_text_flow=False, horizontal_ltr=True, vertical_ttb=True, extra_attrs=[], split_at_punctuation=False, expand_ligatures=True) | 提取包含所有单词及其边界框的列表。单词被定义为字符序列,其中(对于“直立”字符)一个字符的x1和下一个字符的x0之间的差小于等于x_tolerance,且一个字符的doctop和下一个字符的doctop之间的差小于等于y_tolerance。(如果 x_tolerance_ratio 不是 None,提取器将使用等于 x_tolerance_ratio * previous_character["size"] 的动态 x_tolerance)。对于非直立字符,采用类似的方法,但是测量它们之间的垂直距离而不是水平距离。参数horizontal_ltr和vertical_ttb指示单词是从左到右(对于水平文字)/从上到下(对于垂直文字)阅读。将keep_blank_chars设置为True将意味着空字符被视为单词的一部分,而不是单词之间的空格。将use_text_flow设置为True将使用 PDF 的底层字符流作为指导,对单词进行排序和分割,而不是通过 x/y 位置进行预排序(这模拟了在 PDF 中拖动光标突出显示文本的方式;与此相似,顺序不总是看起来很合乎逻辑)。传递一个extra_attrs的列表(例如,["fontname", "size"])将限制每个单词中具有完全相同属性值的字符,并且生成的单词字典将指示这些属性。将split_at_punctuation设置为True将强制在string.punctuation中指定的标点符号处分隔标记;或者你可以通过传递一个字符串来指定分隔标点符号的列表,例如split_at_punctuation='!"&'()\*+,.:;<=>?@[\]^\\\{\\ | \\}~'。除非设置expand_ligatures=False,连字(如 fi)将展开为它们的组合字母(例如fi)。 ||
.extract_text_lines(layout=False, strip=True, return_chars=True, **kwargs) | 实验性功能 返回一个字典列表,代表页面上的文本行。strip参数的工作方式类似于 Python 的str.strip()方法,它返回去除周围空白的text属性。(只在layout=True时相关。)将return_chars设置为False将在返回的文本行字典中排除单个字符对象。剩下的**kwargs是你会传递给.extract_text(layout=True, ...)的参数。 ||
.search(pattern, regex=True, case=True, main_group=0, return_groups=True, return_chars=True, layout=False, **kwargs) | *实验性功能* 搜索页面中的文本,并返回与查询匹配的所有实例的列表。对于每个实例,响应字典对象包含匹配的文本、任何正则表达式组匹配、边界框坐标和字符对象本身。pattern可以是一个已编译的正则表达式、一个未编译的正则表达式或一个非正则字符串。如果regex为False,则将模式视为非正则字符串。如果case为False,则以不区分大小写的方式进行搜索。通过设置main_group,可以将结果限制在pattern中的特定正则表达式组中(默认为 0 表示整个匹配)。将return_groups和/或return_chars设置为False将排除匹配的正则表达式组和/或字符列表(以"groups"和"chars"添加到返回的字典中)。参数layout的操作与.extract_text(...)相同。剩下的**kwargs是你会传递给.extract_text(layout=True, ...)的参数。注意:零宽度和全空白字符的匹配将被丢弃,因为它们(通常)在页面上没有明确的位置。 ||
.dedupe_chars(tolerance=1) | 删除重复的字符-与其他字符共享相同的文本、字体名称、大小和位置(在“公差”x/y 范围内)-已删除. (参考 Issue #71了解该机制) |
提取表格
pdfplumber提取表格大部分借鉴 Anssi Nurminen 的硕士论文, 灵感来源于 Tabula. 工作流程如下:
-
针对 PDF 页面, 查找(a)明确定义的行和/或(b)页面上单词对齐所隐含的行。
-
合并重叠或接近重叠的线条.
-
找出这些线条的交点.
-
找到使用这些交点作为顶点的最细粒度的矩形集(即单元格)。
-
将连续单元格分组到表中。
表格提取方法
pdfplumber.Page页面对象支持以下方法:
| 方法 | 说明 |
|---|---|
.find_tables(table_settings={}) |
返回表格 Table 对象列表. Table包含.cells, .rows,.bbox 属性, 以及方法.extract(x_tolerance=3, y_tolerance=3) |
.find_table(table_settings={}) |
类似.find_tables(...), 只返回页面中最大的表格(Table表格对象). 如果多个表格尺寸一致 — 相同的单元格数量 — 该方法返回最靠页面顶部的表格. |
.extract_tables(table_settings={}) |
返回从页面上找到的所有表中提取的文本,表示为列表列表列表,其结构为“表->行->单元格”。 |
.extract_table(table_settings={}) |
返回从页面上最大表(参考.find_tables(...))中提取的文本,该表表示为列表列表,其结构为“行->单元格”。 |
.debug_tablefinder(table_settings={}) |
返回TableFinder类的实例,该类可以访问.edges(边), .intersections(交点), .cells(单元格)和.tables(表格)属性. |
举例:
123 pdf = pdfplumber.open("path/to/my.pdf")page = pdf.pages[0]page.extract_table()
表格提取配置
默认情况下, extract_tables使用页面的垂直线和水平线(或矩形边)作为单元格分隔符。但该方法可以通过 table_settings参数进行高度自定义。以下是设置参数及默认值:
12345678910111213141516171819202122 { "vertical_strategy": "lines", "horizontal_strategy": "lines", "explicit_vertical_lines": [], "explicit_horizontal_lines": [], "snap_tolerance": 3, "snap_x_tolerance": 3, "snap_y_tolerance": 3, "join_tolerance": 3, "join_x_tolerance": 3, "join_y_tolerance": 3, "edge_min_length": 3, "min_words_vertical": 3, "min_words_horizontal": 1, "intersection_tolerance": 3, "intersection_x_tolerance": 3, "intersection_y_tolerance": 3, "text_tolerance": 3, "text_x_tolerance": 3, "text_y_tolerance": 3, "text_*": …, # 见下文}
| 配置项 | 说明 |
| -------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ |
| "vertical_strategy" | 垂直策略,可选值 "lines", "lines_strict", "text", "explicit".见后续说明 |
| "horizontal_strategy" | 水平策略,可选值 "lines", "lines_strict", "text", "explicit". 见后续说明 |
| "explicit_vertical_lines" | 明确划分表中单元格的垂直线列表。可与上述任何策略结合使用。列表中的项目应该是数字(表示一条直线的x坐标,即页面的全高)或 line/rect/curve对象。 |
| "explicit_horizontal_lines" | 明确划分表中单元格的水平线列表。可与上述任何策略结合使用。列表中的项目应该是数字(表示一条直线的y坐标即页面的全高)或 line/rect/curve对象。 |
| "snap_tolerance", "snap_x_tolerance", "snap_y_tolerance" | snap_tolerance像素内的平行线将“捕捉”到相同的水平或垂直位置。 |
| "join_tolerance", "join_x_tolerance", "join_y_tolerance" | 同一条无限线上的线段,其端点在彼此的join_tolerance范围内,将“连接”为一条线段 |
| "edge_min_length" | 在尝试重建表之前,将丢弃小于edge_min_length的边 |
| "min_words_vertical" | 使用 "horizontal_strategy": "text"时,至少 min_words_horizontal单词必须共享相同的对齐方式。 |
| "min_words_horizontal" | 使用 "horizontal_strategy": "text"时,至少min_words_horizontal单词必须共享相同的对齐方式。 |
| "intersection_tolerance", "intersection_x_tolerance", "intersection_y_tolerance" | 将边组合到单元格中时,正交边必须在intersection_tolerance 像素范围内才能视为相交。 |
| "text_*" | 以text_为前缀的配置项将在表格文本提取时生效. 可以设置Page.extract_text(...)中的参数. |
| "text_x_tolerance", "text_y_tolerance" | text_为前缀的配置项也适用于表格识别算法,也就是说,当该算法搜索单词时,它将期望每个单词中的单个字母之间的距离不超过text\_[x | y]\_tlerance像素. |
表格提取策略
vertical_strategy(垂直策略) 及 horizontal_strategy(水平策略)均包含以下选项:
| 策略 | 说明 |
|---|---|
"lines" |
使用页面的图形线(包括矩形对象的边)作为潜在表格单元格的边框。 |
"lines_strict" |
使用页面的图形线(而不是矩形对象的边)作为潜在表格单元格的边框。 |
"text" |
对于vertical_strategy(垂直策略):推导连接页面上单词的左、右或中心的(假想的)行,并将这些行用作潜在表格单元格的边框。对于horizontal_strategy,相同操作,但使用单词的顶部。 |
"explicit" |
仅使用explicit_vertical_lines / explicit_horizontal_lines中明确定义的线。 |
备注
-
在尝试提取表之前裁剪页面通常很有帮助 —
Page.crop(bounding_box) -
v0.5.0版本的pdfplumber针对表格提取功能进行了彻底的重新设计,并引入了突破性的更改。
提取表单值
有时 PDF 文件可以包含表单,包含了人们可以填写和保存的输入。虽然表单字段中的值与 PDF 文件中的其他文本类似,但表单数据的处理方式不同。如果您想彻底了解详细信息,请参阅本手册第 671 页 specification.
pdfplumber没有用于处理表单数据的接口,但您可以使用pdfplumber对pdfminer的封装组件来访问。
例如,此代码段将检索表单字段名和值,并将它们存储在字典中。
12345678910111213141516171819202122232425262728 import pdfplumberfrom pdfplumber.utils.pdfinternals import resolve_and_decode, resolvepdf = pdfplumber.open("document_with_form.pdf") def parse_field_helper(form_data, field, prefix=None): """ appends any PDF AcroForm field/value pairs in `field` to provided `form_data` list if `field` has child fields, those will be parsed recursively. """ resolved_field = field.resolve() field_name = '.'.join(filter(lambda x: x, [prefix, resolve_and_decode(resolved_field.get("T"))])) if "Kids" in resolved_field: for kid_field in resolved_field["Kids"]: parse_field_helper(form_data, kid_field, prefix=field_name) if "T" in resolved_field or "TU" in resolved_field: # "T" is a field-name, but it's sometimes absent. # "TU" is the "alternate field name" and is often more human-readable # your PDF may have one, the other, or both. alternate_field_name = resolve_and_decode(resolved_field.get("TU")) if resolved_field.get("TU") else None field_value = resolve_and_decode(resolved_field["V"]) if 'V' in resolved_field else None form_data.append([field_name, alternate_field_name, field_value]) form_data = []fields = resolve(pdf.doc.catalog["AcroForm"])["Fields"] for field in fields: form_data[field_name] = field_value
运行以上代码, 得到的form_data是一个包含三元素元组的列表. 例如, 一个包含城市和州值域的 PDF 提取出来的表单如下.
123456 [ ['STATE.0', 'enter STATE', 'CA'], ['section 2 accident infoRmation.1.0', 'enter city of accident', 'SAN FRANCISCO']]
用例演示
-
提取加利福尼亚工人调整和再培训通知(WARN)报告中的表格. 演示基本的可视化调试和表提取。
-
提取 FBI 的国家即时刑事背景调查系统 PDF 文件中的表格. 演示如何使用可视化调试查找最佳的表提取设置。还演示了
Page.crop(...)(页面裁剪) 及Page.extract_text(...).(文本导出) -
从圣何塞局搜索报告中提取等宽数据,
Page.extract_text(...)示例.
与其他库的比较
其他几个 Python 库帮助用户从 PDF 中提取信息。综上所述,pdfplumber通过结合以下功能而区别于其他 PDF 处理库:
-
可以轻松访问每个 PDF 对象的详细信息
-
拥有用于提取文本和表格的更高级、可自定义的方法
-
集成了可视化调试
-
其他有用的实用功能,例如通过裁剪框过滤对象
了解pdfplumber无法提供的功能也很有帮助:
-
创建 PDF
-
修改 PDF
-
文字识别(OCR)
-
完全支持从 OCR 识别过的 PDF 提取表格
特性比较
-
pdfminer.sixpdfplumber是基于该库实现的。它主要关注解析 PDF、分析 PDF 布局和对象定位,以及提取文本。但它不提供用于表提取或可视化调试的工具。 -
PyPDF2是一个纯 Python 库,“能够拆分、合并、裁剪和转换 PDF 文件的页面。它还可以向 PDF 文件添加自定义数据、查看选项和密码。”它可以提取页面文本,但无法轻松访问形状对象(矩形、线条等)、表提取或可视化调试工具。 -
pymupdf运行速度比pdfminer快。可以生成和修改 PDF,但该库需要安装非 Python 软件(MuPDF)。它无法轻松访问形状对象(矩形、直线等),并且不提供表提取或可视化调试工具。 -
camelot,tabula-py, andpdftables这些库主要关注表格提取。在某些情况下,它们可能更适合提取特定的表格。
认可 / 贡献
非常感谢以下提供了想法、功能和修复的用户:
- Jacob Fenton
- Dan Nguyen
- Jeff Barrera
- Bob Lannon
- Dustin Tindall
- @yevgnen
- @meldonization
- Oisín Moran
- Samkit Jain
- Francisco Aranda
- Kwok-kuen Cheung
- Marco
- Idan David
- @xv44586
- Alexander Regueiro
- Daniel Peña
- @bobluda
- @ramcdona
- @johnhuge
- Jhonatan Lopes
- Ethan Corey
- Shannon Shen
- Matsumoto Toshi
- John West
- David Huggins-Daines
- Jeremy B. Merrill
- Echedey Luis
- Andy Friedman
贡献者
欢迎贡献代码,由于该库正在积极维护, 请先提交提案
主要维护者:
免责声明 © 2025 - 虚宝阁
本站部分源码来源于网络,版权归属原开发者,用户仅获得使用权。依据《计算机软件保护条例》第十六条,禁止:
- 逆向工程破解技术保护措施
- 未经许可的分发行为
- 去除源码中的原始版权标识
※ 本站源码仅用于学习和研究,禁止用于商业用途。如有侵权, 请及时联系我们进行处理。