查看 PDF 以获取有关每个文本字符、矩形和线条的详细信息。另外:表格提取和可视化调试。
最适合机器生成的 PDF,而不是扫描的 PDF。基于pdfminer.six
构建。
目前在 Python 3.8、3.9、3.10、3.11 上进行测试。
本文件有中文版本(作者:@hbh112233abc)。
要报告错误或请求功能,请提交问题。要针对特定 PDF 提出问题或请求帮助,请使用讨论论坛。
pip install pdfplumber
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 [format] | csv 或json 。 json 格式返回更多信息;它包括 PDF 级和页面级元数据,以及字典嵌套属性。 |
--pages [list of pages] | 以空格分隔、 1 索引的页面或连字符页面范围列表。例如, 1, 11-15 ,它将返回第 1、11、12、13、14 和 15 页的数据。 |
--types [list of object types to extract] | 选项有char 、 rect 、 line 、 curve 、 image 、 annot 等。默认为所有可用。 |
--laparams | 传递给pdfplumber.open(..., laparams=...) JSON 格式字符串(例如'{"detect_vertical": true}' )。 |
--precision [integer] | 对浮点数进行四舍五入的小数位数。默认为不舍入。 |
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)
,其中x
可以是:
open
方法返回pdfplumber.PDF
类的实例。
要加载受密码保护的 PDF,请传递password
关键字参数,例如pdfplumber.open("file.pdf", password = "test")
。
要将布局分析参数设置为pdfminer.six
的布局引擎,请传递laparams
关键字参数,例如pdfplumber.open("file.pdf", laparams = { "line_overlap": 0.7 })
。
要预规范化 Unicode 文本,请传递unicode_norm=...
,其中...
是四种 Unicode 规范化形式之一: "NFC"
、 "NFD"
、 "NFKC"
或"NFKD"
。
默认情况下,无效的元数据值将被视为警告。如果不是故意的,请将strict_metadata=True
传递给open
方法,如果pdfplumber.open
无法解析元数据,它将引发异常。
pdfplumber.PDF
类顶级pdfplumber.PDF
类表示单个 PDF,并具有两个主要属性:
财产 | 描述 |
---|---|
.metadata | 元数据键/值对的字典,取自 PDF 的Info 预告片。通常包括“CreationDate”、“ModDate”、“Producer”等。 |
.pages | 每加载一页包含一个pdfplumber.Page 实例的列表。 |
...还有以下方法:
方法 | 描述 |
---|---|
.close() | 调用此方法会在每个页面上调用Page.close() ,并且还会关闭文件流(除非流是外部的,即已经打开并直接传递给pdfplumber )。 |
pdfplumber.Page
类pdfplumber.Page
类是pdfplumber
的核心。您将使用pdfplumber
做的大多数事情都将围绕此类进行。它具有以下主要属性:
财产 | 描述 |
---|---|
.page_number | 连续页码,第一页从1 开始,第二页从2 开始,依此类推。 |
.width | 页面的宽度。 |
.height | 页面的高度。 |
.objects / .chars / .lines / .rects / .curves / .images | 这些属性中的每一个都是一个列表,每个列表都为页面上嵌入的每个此类对象包含一个字典。有关更多详细信息,请参阅下面的“对象”。 |
...以及这些主要方法:
方法 | 描述 |
---|---|
.crop(bounding_box, relative=False, strict=True) | 返回裁剪到边界框的页面版本,该版本应表示为值为(x0, top, x1, bottom) 的 4 元组。裁剪后的页面保留至少部分落在边界框内的对象。如果对象仅部分落入框内,则其尺寸将被切片以适合边界框。如果relative=True ,则边界框将计算为距页面边界框左上角的偏移量,而不是绝对定位。 (有关视觉示例和说明,请参阅问题 #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) | 返回仅包含test_function(obj) 返回True 的.objects 的页面版本。 |
...还有以下方法:
方法 | 描述 |
---|---|
.close() | 默认情况下, Page 对象会缓存其布局和对象信息,以避免重新处理它。然而,在解析大型 PDF 时,这些缓存的属性可能需要大量内存。您可以使用此方法刷新缓存并释放内存。 |
以下各节描述了其他方法:
pdfplumber.PDF
和pdfplumber.Page
的每个实例都提供对多种类型 PDF 对象的访问,所有这些对象均源自pdfminer.six
PDF 解析。以下属性均返回匹配对象的 Python 列表:
.chars
,每个代表一个文本字符。.lines
,每个代表一条一维线。.rects
,每个代表一个二维矩形。.curves
,每个代表pdfminer.six
无法识别为直线或矩形的任何一系列连接点。.images
,每个代表一个图像。.annots
,每个代表一个 PDF 注释(详细信息请参阅官方 PDF 规范的第 8.4 节).hyperlinks
,每个代表Link
子类型的单个 PDF 注释并具有URI
操作属性每个对象都表示为一个简单的 Python dict
,具有以下属性:
char
属性财产 | 描述 |
---|---|
page_number | 找到该字符的页码。 |
text | 例如,“z”、“Z”或“”。 |
fontname | 角色字体的名称。 |
size | 字体大小。 |
adv | 等于文本宽度 * 字体大小 * 缩放系数。 |
upright | 性格是否正直。 |
height | 角色的高度。 |
width | 字符的宽度。 |
x0 | 字符左侧距页面左侧的距离。 |
x1 | 字符右侧与页面左侧的距离。 |
y0 | 字符底部距页面底部的距离。 |
y1 | 字符顶部到页面底部的距离。 |
top | 字符顶部到页面顶部的距离。 |
bottom | 字符底部到页面顶部的距离。 |
doctop | 字符顶部到文档顶部的距离。 |
matrix | 该角色的“当前变换矩阵”。 (详情请参阅下文。) |
mcid | 该字符的标记内容部分 ID(如果有)(否则None )。实验属性。 |
tag | 该字符的标记内容部分标签(如果有)(否则为None )。实验属性。 |
ncs | TKTK |
stroking_pattern | TKTK |
non_stroking_pattern | TKTK |
stroking_color | 字符轮廓(即笔划)的颜色。有关详细信息,请参阅 docs/colors.md。 |
non_stroking_color | 角色的内部颜色。有关详细信息,请参阅 docs/colors.md。 |
object_type | “字符” |
注意:字符的matrix
属性表示“当前变换矩阵”,如 PDF 参考(第 6 版)第 4.2.2 节中所述。矩阵控制角色的比例、倾斜和位置平移。旋转是缩放和倾斜的组合,但在大多数情况下可以认为等于 x 轴倾斜。 pdfplumber.ctm
子模块定义了一个类CTM
来协助这些计算。例如:
from pdfplumber . ctm import CTM
my_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 | 该行的标记内容部分标签(如果有)(否则为None )。实验属性。 |
object_type | “线” |
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 | 该矩形的标记内容部分标签(如果有)(否则为None )。实验属性。 |
object_type | “直” |
curve
属性财产 | 描述 |
---|---|
page_number | 找到该曲线的页码。 |
pts | (x, top) 元组列表,指示曲线上的点。 |
path | 描述完整路径描述的(cmd, *(x, top)) 元组列表,包括(例如)贝塞尔曲线中使用的控制点。 |
height | 曲线边界框的高度。 |
width | 曲线边界框的宽度。 |
x0 | 曲线最左边的点距页面左侧的距离。 |
x1 | 曲线最右点到页面左侧的距离。 |
y0 | 曲线最低点距页面底部的距离。 |
y1 | 曲线最高点距页面底部的距离。 |
top | 曲线最高点距页面顶部的距离。 |
bottom | 曲线最低点距页面顶部的距离。 |
doctop | 曲线最高点距文档顶部的距离。 |
linewidth | 线的粗细。 |
fill | 曲线路径定义的形状是否被填充。 |
stroking_color | 曲线轮廓的颜色。有关详细信息,请参阅 docs/colors.md。 |
non_stroking_color | 曲线的填充颜色。有关详细信息,请参阅 docs/colors.md。 |
dash | 描述曲线虚线样式的([dash_array], dash_phase) 元组。详细信息请参见 PDF 规范的表 4.6。 |
mcid | 该曲线的标记内容部分 ID(如果有)(否则None )。实验属性。 |
tag | 该曲线的标记内容部分标签(如果有)(否则None )。实验属性。 |
object_type | “曲线” |
此外, pdfplumber.PDF
和pdfplumber.Page
都提供对多个派生对象列表的访问: .rect_edges
(将每个矩形分解为四条线)、. .curve_edges
(对curve
对象执行相同操作)和.edges
(将.rect_edges
、 .curve_edges
和.lines
)。
image
属性注意:虽然可以通过pdfplumber
获得image
对象的定位和特征,但该库不提供对重建图像内容的直接支持。为此,请参阅此建议。
财产 | 描述 |
---|---|
page_number | 找到图像的页码。 |
height | 图像的高度。 |
width | 图像的宽度。 |
x0 | 图像左侧距页面左侧的距离。 |
x1 | 图像右侧与页面左侧的距离。 |
y0 | 图像底部到页面底部的距离。 |
y1 | 图像顶部到页面底部的距离。 |
top | 图像顶部到页面顶部的距离。 |
bottom | 图像底部到页面顶部的距离。 |
doctop | 矩形顶部到文档顶部的距离。 |
srcsize | 图像原始尺寸,作为(width, height) 元组。 |
colorspace | 图像的颜色域(例如,RGB)。 |
bits | 每个颜色分量的位数;例如,8 对应于每个颜色分量(RGB 颜色空间中的 R、G 和 B)的 255 个可能值。 |
stream | 图像的像素值,作为pdfminer.pdftypes.PDFStream 对象。 |
imagemask | 可为 null 的布尔值;如果为True ,“指定图像数据将用作以当前颜色绘制的模板蒙版。” |
mcid | 该图像的标记内容部分 ID(如果有)(否则None )。实验属性。 |
tag | 该图像的标记内容部分标签(如果有)(否则None )。实验属性。 |
object_type | “图像” |
pdfminer.six
获取更高级别的布局对象如果将pdfminer.six
-handling laparams
参数传递给pdfplumber.open(...)
,则每个页面的.objects
字典还将包含pdfminer.six
的更高级别布局对象,例如"textboxhorizontal"
。
pdfplumber
的可视化调试工具有助于理解 PDF 的结构以及从中提取的对象。
.to_image()
创建PageImage
要将任何页面(包括裁剪后的页面)转换为PageImage
对象,请调用my_page.to_image()
。您可以选择传递以下关键字参数之一:
resolution
:每英寸所需的像素数。默认值: 72
。类型: int
。width
:所需的图像宽度(以像素为单位)。默认值:未设置,由resolution
决定。类型: int
。height
:所需的图像宽度(以像素为单位)。默认值:未设置,由resolution
决定。类型: int
。antialias
:创建图像时是否使用抗锯齿。设置为True
会创建锯齿状文本和图形较少的图像,但文件大小较大。默认值: False
。类型: bool
。force_mediabox
:使用页面的.mediabox
尺寸,而不是.cropbox
尺寸。默认值: False
。类型: bool
。例如:
im = my_pdf . pages [ 0 ]. to_image ( resolution = 150 )
从脚本或 REPL 中, 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", quantize=True, colors=256, bits=8) | 将带注释的图像另存为 PNG 文件。默认参数将图像量化为 256 色调色板,以 8 位颜色深度保存 PNG。您可以通过传递quantize=False 禁用量化,或通过传递colors=N 调整调色板的大小。 |
您可以将显式坐标或任何pdfplumber
PDF 对象(例如,字符、行、矩形)传递给这些方法。
单对象方法 | 散装法 | 描述 |
---|---|---|
im.draw_line(line, stroke={color}, stroke_width=1) | im.draw_lines(list_of_lines, **kwargs) | 从line 、 curve 或 2 元组的 2 元组中绘制一条线(例如, ((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
方法的基础上,但参数已经过调整,以便与 SVG 的fill
/ stroke
/ stroke_width
命名法保持一致。
im.debug_tablefinder(table_settings={})
将返回 PageImage 的版本,其中检测到的线条(红色)、交叉点(圆圈)和表格(浅蓝色)重叠。
pdfplumber
可以从任何给定页面(包括裁剪和派生页面)中提取文本。它还可以尝试保留该文本的布局,以及识别单词和搜索查询的坐标。 Page
对象可以调用以下文本提取方法:
方法 | 描述 |
---|---|
.extract_text(x_tolerance=3, x_tolerance_ratio=None, y_tolerance=3, layout=False, x_density=7.25, y_density=13, line_dir_render=None, char_dir_render=None, **kwargs) | 将页面的所有字符对象整理成单个字符串。
|
.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, line_dir="ttb", char_dir="ltr", line_dir_rotated="ttb", char_dir_rotated="ltr", extra_attrs=[], split_at_punctuation=False, expand_ligatures=True, return_chars=False) | 返回所有看起来像单词的事物及其边界框的列表。单词被认为是字符序列,其中(对于“直立”字符)一个字符的x1 和下一个字符的x0 之间的差异小于或等于x_tolerance ,并且其中一个字符的doctop 和下一个字符的doctop 小于或等于y_tolerance 。 (如果x_tolerance_ratio 不是None ,则提取器使用等于x_tolerance_ratio * previous_character["size"] 动态x_tolerance 。)对于非直立字符采用类似的方法,但测量它们之间的垂直距离,而不是水平距离。将keep_blank_chars 更改为True 将意味着空白字符被视为单词的一部分,而不是单词之间的空格。将use_text_flow 更改为True 将使用 PDF 的底层字符流作为对单词进行排序和分段的指南,而不是按 x/y 位置对字符进行预排序。 (这模仿了拖动光标如何突出显示 PDF 中的文本;与此类似,顺序并不总是看起来符合逻辑。)参数line_dir 和char_dir 告诉此方法预期读取行/字符的方向;有效选项为“ttb”(从上到下)、“btt”(从下到上)、“ltr”(从左到右)和“rtl”(从右到左)。 line_dir_rotated 和char_dir_rotated 参数类似,但针对的是已旋转的文本。传递extra_attrs 列表(例如, ["fontname", "size"] 会将每个单词限制为与每个属性共享完全相同值的字符,并且生成的单词字典将指示这些属性。将split_at_punctuation 设置为True 将在string.punctuation 指定的标点符号处强制中断标记;或者您可以通过传递字符串来指定分隔标点符号的列表,例如, split_at_punctuation='!"&'()*+,.:;<=>?@[]^`{|}~' 。除非您设置expand_ligatures=False ,否则fi 之类的连字将扩展为其组成字母(例如、 fi )。传递return_chars=True 将向每个单词词典添加其组成字符的列表,作为"chars" 字段中的列表。 |
.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) | 实验性功能,允许您搜索页面文本,返回与查询匹配的所有实例的列表。对于每个实例,响应字典对象包含匹配文本、任何正则表达式组匹配、边界框坐标以及 char 对象本身。 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, extra_attrs=("fontname", "size")) | 返回具有重复字符(与其他字符共享相同文本、定位(在 x/y tolerance 内)和extra_attrs 的重复字符)的页面版本。 (请参阅问题 #71 了解动机。) |
pdfplumber
的表检测方法大量借鉴了 Anssi Nurminen 的硕士论文,并受到 Tabula 的启发。它的工作原理如下:
pdfplumber.Page
对象可以调用以下表方法:
方法 | 描述 |
---|---|
.find_tables(table_settings={}) | 返回Table 对象的列表。 Table 对象提供对.cells 、 .rows 、 .columns 和.bbox 属性以及.extract(x_tolerance=3, y_tolerance=3) 方法的访问。 |
.find_table(table_settings={}) | 与.find_tables(...) 类似,但返回页面上最大的表,作为Table 对象。如果多个表格具有相同的大小(以单元格数量衡量),则此方法返回最接近页面顶部的表格。 |
.extract_tables(table_settings={}) | 返回从页面上找到的所有表格中提取的文本,表示为列表的列表的列表,结构为table -> row -> cell 。 |
.extract_table(table_settings={}) | 返回从页面上最大的表格中提取的文本(请参阅上面的.find_table(...) ),表示为列表的列表,其结构为row -> cell 。 |
.debug_tablefinder(table_settings={}) | 返回TableFinder 类的实例,可以访问.edges 、 .intersections 、 .cells 和.tables 属性。 |
例如:
pdf = pdfplumber . open ( "path/to/my.pdf" )
page = pdf . pages [ 0 ]
page . extract_table ()
单击此处查看更详细的示例。
默认情况下, extract_tables
使用页面的垂直线和水平线(或矩形边缘)作为单元格分隔符。但该方法可以通过table_settings
参数进行高度自定义。可能的设置及其默认值:
{
"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_*" : …, # See below
}
环境 | 描述 |
---|---|
"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" | 当使用"vertical_strategy": "text" 时,至少min_words_vertical 个单词必须共享相同的对齐方式。 |
"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_ 为前缀的设置也适用于表识别算法。即,当该算法搜索单词时,它将期望每个单词中的各个字母之间的距离不超过text_x_tolerance / text_y_tolerance 点。 |
vertical_strategy
和horizontal_strategy
都接受以下选项:
战略 | 描述 |
---|---|
"lines" | 使用页面的图形线(包括矩形对象的边)作为潜在表格单元格的边框。 |
"lines_strict" | 使用页面的图形线(而不是矩形对象的边)作为潜在表格单元格的边框。 |
"text" | 对于vertical_strategy :推导连接页面上单词的左侧、右侧或中心的(假想)线,并将这些线用作潜在表格单元格的边框。对于horizontal_strategy ,相同但使用单词的顶部。 |
"explicit" | 仅使用在explicit_vertical_lines / explicit_horizontal_lines 中显式定义的线。 |
通常,在尝试提取表格之前裁剪页面( Page.crop(bounding_box)
会很有帮助。
pdfplumber
的表提取在v0.5.0
中进行了彻底的重新设计,并引入了重大更改。
有时,PDF 文件可能包含表单,其中包含人们可以填写和保存的输入。虽然表单字段中的值与 PDF 文件中的其他文本类似,但表单数据的处理方式有所不同。如果您想了解详细信息,请参阅本规范的第 671 页。
pdfplumber
没有用于处理表单数据的接口,但您可以使用pdfplumber
的pdfminer
包装器来访问它。
例如,此代码片段将检索表单字段名称和值并将它们存储在字典中。
import pdfplumber
from pdfplumber . utils . pdfinternals import resolve_and_decode , resolve
pdf = 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 ( resolve ( pdf . doc . catalog [ "AcroForm" ])[ "Fields" ])
for field in fields :
parse_field_helper ( form_data , field )
运行此脚本后, form_data
是一个列表,其中包含每个表单元素的三元素元组。例如,包含城市和州字段的 PDF 表单可能如下所示。
[
['STATE.0', 'enter STATE', 'CA'],
['section 2 accident infoRmation.1.0',
'enter city of accident',
'SAN FRANCISCO']
]
感谢@jeremybmerrill 帮助维护上面的表单解析代码。
extract_table
。演示基本的可视化调试和表格提取。extract_table
。演示如何使用可视化调试来查找最佳表提取设置。还演示了Page.crop(...)
和Page.extract_text(...).
curve
对象。Page.extract_text(...)
的示例。 其他几个 Python 库可帮助用户从 PDF 中提取信息。作为一个广泛的概述, pdfplumber
通过结合以下功能来区别于其他 PDF 处理库:
了解pdfplumber
不提供哪些功能也很有帮助:
pdfminer.six
为pdfplumber
提供了基础。它主要侧重于解析 PDF、分析 PDF 布局和对象定位以及提取文本。它不提供用于表提取或可视化调试的工具。
PyPDF2
是一个纯 Python 库,“能够分割、合并、裁剪和转换 PDF 文件的页面。它还可以向 PDF 文件添加自定义数据、查看选项和密码。”它可以提取页面文本,但不提供对形状对象(矩形、线条等)、表格提取或可视化调试工具的轻松访问。
pymupdf
比pdfminer.six
(因此也比pdfplumber
)快得多,并且可以生成和修改 PDF,但该库需要安装非 Python 软件 (MuPDF)。它还无法轻松访问形状对象(矩形、线条等),并且不提供表格提取或可视化调试工具。
camelot
、 tabula-py
和pdftables
都主要专注于提取表格。在某些情况下,它们可能更适合您尝试提取的特定表。
非常感谢以下用户提供的想法、功能和修复:
欢迎请求请求,但请先提交提案问题,因为该库正在积极开发中。
当前维护者: