pdfplumber - pdf 数据提取

2024-08-23 07:20
文章标签 数据 提取 pdf pdfplumber

本文主要是介绍pdfplumber - pdf 数据提取,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

    • 一、关于 pdfplumber
      • 安装
    • 二、命令行界面
      • 1、基本示例
      • 2、选项
    • 三、Python库
      • 1、基本示例
      • 2、加载PDF
      • 3、`pdfplumber.PDF`类
      • 4、`pdfplumber.Page` 类
      • 5、对象
        • `char`特性
        • `line`属性
        • `rect`属性
        • `curve` 属性
        • 派生属性
        • `image`属性
      • 6、通过pdfminer获取更高级别的`pdfminer.six`
    • 四、可视化调试
      • 1、创建一个`PageImage`与`.to_image()`
      • 2、基本`PageImage`方法
      • 3、绘图方法
      • 4、可视化调试表查找器
    • 五、提取文本
    • 六、提取表
      • 1、表提取方法
      • 2、表提取设置
      • 3、表提取策略
      • 4、笔记
    • 七、提取表单值
    • 八、演示
    • 九、与其他库的比较
      • 具体比较

一、关于 pdfplumber

  • github : https://github.com/jsvine/pdfplumber

Plumb 一个 PDF 以获取每个文本字符、矩形和线条的详细信息。另外:表格提取和可视化调试。

在机器生成 而不是 扫描的PDF上 工作得最好。

pdfminer.six 基础上开发。

目前在 Python 3.8, 3.9, 3.10, 3.11 上 进行了测试。

本文件的翻译版本为:中文(by@hbh112233abc)。

要报告bug或请求功能,请提交问题。要提出问题或请求特定PDF的帮助,请使用讨论论坛。


安装

pip install pdfplumber

二、命令行界面


1、基本示例

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中每个字符、行和矩形的信息。


2、选项

参数描述
--format [format]csvjsonjson格式返回更多信息;它包括PDF级别和页面级别的元数据,以及字典嵌套属性。
--pages [list of pages]以空格分隔, 1索引页面列表或连字符页面范围。
例如,1, 11-15,它将返回第1、11、12、13、14和15页的数据。
--types [list of object types to extract]可选择 charrectlinecurveimageannot等等。默认为所有可用。
--laparamsJSON格式的字符串( 例如,'{"detect_vertical": true}')传递给pdfplumber.open(..., laparams=...)
--precision [integer]四舍五入浮点数的小数位数。默认为不四舍五入。

三、Python库


1、基本示例

import pdfplumberwith pdfplumber.open("path/to/file.pdf") as pdf:first_page = pdf.pages[0]print(first_page.chars[0])

2、加载PDF

要开始使用PDF,请调用pdfplumber.open(x),其中x可以是:

  • PDF文件的路径
  • 文件对象,以字节形式加载
  • 类似文件的对象,以字节形式加载

这个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将引发异常。


3、pdfplumber.PDF

顶级的pdfplumber.PDF类表示单个PDF,并具有两个主要属性:

属性描述
.metadata元数据键/值对的字典,从PDF的Info预告片中提取。通常包括“CreationDate”、“ModDate”、“Producer”等。
.pages每个加载的页面包含一个pdfplumber.Page实例的列表。

… 并且还具有以下方法:

方法描述
.close()调用此方法会在每个页面上调用Page.close(),并且还会关闭文件流(除了流是外部的情况,即已经打开并直接传递给pdfplumber)。

4、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)返回裁剪到边界框的页面版本,该版本应表示为带有值的4元组(x0, top, x1, bottom)
裁剪的页面保留至少部分位于边界框内的对象。
如果对象仅部分位于框内,则对其尺寸进行切片以适应边界框。
如果relative=True,边界框的计算方法是与页面边界框左上角的偏移量,而不是绝对定位。(请参阅问题#245strict=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时,这些缓存的属性可能需要大量内存。
您可以使用此方法刷新缓存并释放内存。

以下各节介绍了其他方法:

  • 可视化调试
  • 提取文本
  • 提取表

5、对象

每个pdfplumber.PDFpdfplumber.Page实例 都提供对多种类型的PDF对象的访问,所有这些对象都派生自pdfminer.sixPDF解析。

以下属性分别返回匹配对象的Python列表:

  • .chars,每个代表一个文本字符。
  • .lines,每个表示一条一维线。
  • .rects,每个表示一个二维矩形。
  • .curves,每个代表pdfminer.six无法识别为线或矩形的任何一系列连接点。
  • .images,每个代表一个图像。
  • .annots,每个代表一个PDF注释(详细信息参见官方PDF规范的第8.4节)
  • .hyperlinks,每个表示子类型Link的单个PDF注释,并具有URI操作属性

每个对象都表示为一个简单的Pythondict,具有以下属性:

char特性
属性描述
page_number找到此字符的页码。
text例如,zZ 或 “”。
fontname字符字体的名称。
size字体大小。
adv等于文本宽度字体大小缩放系数。
upright字符是否直立。
height字符的高度。
width字符的宽度。
x0字符左侧到页面左侧的距离。
x1字符右侧到页面左侧的距离。
y0字符底部到页面底部的距离。
y1字符顶部到页面底部的距离。
top字符顶部到页面顶部的距离。
bottom字符底部到页面顶部的距离页面。
doctop字符顶部与文档顶部的距离。
matrix此字符的“当前转换矩阵”。(详见下文。)
mcid此字符的标记内容部分ID(如果有)(否则None)。实验属性。
tag此字符的标记内容部分标签(如果有)(否则None)。实验属性。
ncsTKTK
stroking_patternTKTK
non_stroking_patternTKTK
stroking_color字符轮廓(即笔画)的颜色。详见docs/colors.md。
non_stroking_color字符的内部颜色。详见docs/colors.md。
object_type“char”

注意:字符的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“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此rect的标记内容部分ID(如果有)(否则None)。实验属性.
tag此rect的标记内容部分标记(如果有)(否则None)。实验属性。
object_type“rect”

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。
dashA([dash_array], dash_phase)描述曲线破折号样式的元组。详见PDF规范的表4.6。
mcid此曲线的标记内容节ID(否则None)。实验属性。
tag此曲线的标记内容节标签(否则None<–atag–20/>)。实验属性。
object_type“曲线”

派生属性

此外,pdfplumber.PDFpdfplumber.Page都提供了 对多个派生对象列表的访问:.rect_edges(将每个矩形分解为四行),.curve_edges(对curve对象做同样的事情)和.edges(结合了.rect_edges.curve_edges.lines)。


image属性

注意:虽然image对象的定位和特征可以通过pdfplumber获得,但此库不提供对重建图像内容的直接支持。为此,请参阅此建议。

属性描述
page_number找到图像的页码。
height图像的高度。
width图像的宽度。
x0图像左侧到页面左侧的距离。
x1图像右侧到页面左侧的距离。
y0图像底部到页面底部的距离。
y1图像顶部到页面底部的距离。
top图像顶部到页面顶部的距离。
bottom图像底部到页面顶部的距离。
doctop矩形顶部到文档顶部的距离。
srcsize图像原始尺寸,作为(width, height)元组。
colorspace图像的颜色域(例如,RGB)。
bits
stream图像的像素值,作为pdfminer.pdftypes.PDFStream对象。
imagemask一个可为空的布尔值;如果True,“指定图像数据将用作以当前颜色绘制的模板蒙版。”
mcid此图像的标记内容部分ID(如果有)(否则None)。实验属性。
tag此图像的标记内容部分标签(如果有)(否则None)。实验属性。
object_type“图像”

6、通过pdfminer获取更高级别的pdfminer.six

如果您将pdfminer.six-处理laparams参数传递给pdfplumber.open(...),那么每个页面的.objects字典也将包含pdfminer.six的高级布局对象,例如"textboxhorizontal"


四、可视化调试

pdfplumber的可视化调试工具有助于理解PDF的结构和从中提取的对象。


1、创建一个PageImage.to_image()

要将任何页面(包括裁剪的页面)转换为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实例所做的更改。


2、基本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来调整调色板的大小。

3、绘图方法

您可以将显式坐标或任何pdfplumberPDF对象(例如char、line、rect)传递给这些方法。

单对象方法批量方法描述
im.draw_line(line, stroke={color}, stroke_width=1)im.draw_lines(list_of_lines, **kwargs)linecurve或2元组的2元组(例如,((x, y), (x, y)))中绘制一条线。
im.draw_vline(location, stroke={color}, stroke_width=1)im.draw_vlines(list_of_locations, **kwargs)location.
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
im.draw_circle(center_or_obj, radius=5, fill={color}, stroke={color})im.draw_circles(list_of_circles, **kwargs)(x, y)坐标或charrect等的中心绘制一个圆。

注意:上面的方法建立在Pillow的ImageDraw方法上,但是参数已经过调整,以与SVG的fill/stroke/stroke_width术语保持一致。


4、可视化调试表查找器

im.debug_tablefinder(table_settings={})将返回PageImage的一个版本,其中覆盖了检测到的线(红色)、交叉点(圆圈)和表格(浅蓝色)。


五、提取文本

pdfplumber可以从任何给定页面(包括裁剪和派生页面)中提取文本。它还可以尝试保留该文本的布局,以及识别单词和搜索查询的坐标。Page对象可以调用以下文本提取方法:


1、.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)

将页面的所有字符对象整理成一个字符串。

  • layout=False时:添加一个字符的x1和下一个字符的x0之间的差异大于x_tolerance
    (如果x_tolerance_ratio不是None,则提取器使用动态x_tolerance等于x_tolerance_ratio * previous_character["size"]。)
    添加换行符,其中一个字符的doctop和下一个字符的doctop之间的差异大于y_tolerance
  • layout=True实验特征):尝试模仿页面上文本的结构布局,使用x_densityy_density确定每个“点”的最小字符/换行符数,PDF测量单位。
    传递line_dir_render="ttb"/"btt"/"ltr"/"rtl"和/或char_dir_render="ttb"/"btt"/"ltr"/"rtl"将以与默认不同的方向输出行/字符。
    所有剩余的**kwargs被传递到.extract_words(...)(见下文),计算布局的第一步。

2、.extract_text_simple(x_tolerance=3, y_tolerance=3)

稍快但不太灵活的版本.extract_text(...),使用更简单的逻辑。


3、.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等于x_tolerance_ratio * previous_character["size"].)非直立字符也采用了类似的方法,但测量它们之间的垂直距离,而不是水平距离。
keep_blank_chars更改为True将意味着空白字符被视为单词的一部分,而不是单词之间的空格。
use_text_flow更改为True将使用PDF的基础字符流作为单词排序和分割的指南,而不是按x/y位置预先排序字符。
(这模仿了拖动光标如何突出显示PDF中的文本;因此,顺序似乎并不总是合乎逻辑的。)line_dirchar_dir参数告诉此方法预期读取行/字符的方向;有效选项是“ttb”(从上到下)、“btt”(从下到上)、“ltr”(从左到右)和“rtl”(从右到左)。
line_dir_rotatedchar_dir_rotated参数相似,但用于已旋转的文本。
传递extra_attrs(例如,["fontname", "size"]将每个单词限制为与每个属性共享完全相同值的字符,生成的单词字典将指示这些属性。
split_at_punctuation设置为True将在以下指定的标点符号处强制执行中断标记string.punctuation;或者您可以通过传递字符串来指定分隔标点符号的列表,例如,split_at_punctuation='!"&'()*+,.:;<=>?@[]^{|}~'。 除非您设置expand_ligatures=False,否则连字符如将扩展为它们的组成字母(例如,fi)。 传递return_chars=True将向每个单词字典添加其组成字符的列表,作为"chars"`字段中的列表。


4、.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, ...)


5、.search(pattern, regex=True, case=True, main_group=0, return_groups=True, return_chars=True, layout=False, **kwargs)

实验功能,允许您搜索页面的文本,返回与查询匹配的所有实例的列表。
对于每个实例,响应字典对象包含匹配的文本、任何正则表达式组匹配、边界框坐标和char对象本身。
pattern可以是编译的正则表达式、未编译的正则表达式或非正则表达式字符串。
如果regexFalse,则该模式被视为非正则表达式字符串。
如果caseFalse,则以不区分大小写的方式执行搜索。
设置main_group将结果限制为pattern内的特定正则表达式组(默认值为0表示整个匹配)。
return_groups和/或return_chars设置为False将排除添加匹配的正则表达式组和/或字符的列表(作为"groups""chars"到返回字典)。
layout参数的操作方式与.extract_text(...)一样。
其余的**kwargs是您将传递给的.extract_text(layout=True, ...)
注意:零宽度和全空白匹配被丢弃,因为它们(通常)在页面上没有明确的位置。


6、.dedupe_chars(tolerance=1, extra_attrs=("fontname", "size"))

返回具有重复字符的页面版本-那些共享相同文本、定位(在tolerancex/y内)和与其他字符相同的字符-已删除。
(请参阅extra_attrs问题#71以了解动机。) |


六、提取表

pdfplumber的表格检测方法大量借鉴了Anssi Urminen的硕士论文,并受到Tabula的启发。它的工作原理是这样的:

  1. 对于任何给定的PDF页面,找到(a)明确定义和/或(b)由页面上的单词对齐暗示的行。
  2. 合并重叠或几乎重叠的线。
  3. 找出所有这些线的交点。
  4. 找到使用这些交点作为顶点的最粒度的矩形集(即单元格)。
  5. 将连续的单元格分组到表格中。

1、表提取方法

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()

单击此处查看更详细的示例。


2、表提取设置

默认情况下,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策略时的table-identification算法。即,当该算法搜索单词时,它会期望每个单词中的单个字母相距不超过text_x_tolerance/text_y_tolerance点。

3、表提取策略

两个vertical_strategyhorizontal_strategy都接受以下选项:

策略描述
"lines"使用页面的图形线条——包括矩形对象的边——作为潜在表格单元格的边框。
"lines_strict"使用页面的图形线条——但不包括矩形对象的边——作为潜在表格单元格的边框。
"text"对于vertical_strategy:推导连接页面左、右或中心单词的(想象的)线条,并使用这些线条作为潜在表格单元格的边框。对于horizontal_strategy,相同但使用单词顶部。
"explicit"仅使用explicit_vertical_lines/explicit_horizontal_lines.

4、笔记

  • 在尝试提取表之前,裁剪一个页面Page.crop(bounding_box)通常很有帮助。
  • 表提取pdfplumber从根本上重新设计v0.5.0,并引入了突破性的变化。

七、提取表单值

有时,PDF文件可以包含包含人们可以填写和保存的输入的表单。虽然表单字段中的值看起来像PDF文件中的其他文本,但表单数据的处理方式不同。如果您想要血淋淋的详细信息,请参阅本规范的第671页。

pdfplumber没有处理表单数据的接口,但您可以使用pdfplumberpdfminer包装器访问它。

例如,此片段将检索表单字段名称和值并将它们存储在字典中。

import pdfplumber
from 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` listif `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 Nonefield_value = resolve_and_decode(resolved_field["V"]) if 'V' in resolved_field else Noneform_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帮助维护上面的表单解析代码。


八、演示

  • 在 California Worker Adjustment and Retraining Notification (WARN) report 上使用 extract_table。演示基本的可视化调试和表格提取。
  • 在 FBI’s National Instant Criminal Background Check System PDFs 上使用 extract_table。演示如何使用可视化调试来找到最佳的表格提取设置。还演示了Page.crop(...)Page.extract_text(...).
  • 检查和可视化curve对象。
  • 从 San Jose PD firearm search report 提取固定宽度数据 ,使用的示例Page.extract_text(...)

九、与其他库的比较

其他几个Python库帮助用户从PDF中提取信息。作为一个广泛的概述,pdfplumber通过结合以下特性将自己与其他PDF处理库区分开来:

  • 轻松访问有关每个PDF对象的详细信息
  • 用于提取文本和表格的高级、可定制的方法
  • 紧密集成的可视化调试
  • 其他有用的实用功能,例如通过裁剪框过滤对象

了解pdfplumber提供哪些功能也很有帮助:

  • PDF生成
  • PDF修改
  • 光学字符识别(OCR)
  • 强大的支持从OCR文档中提取表格

具体比较

  • pdfminer.six提供了pdfplumber的基础,主要关注解析PDF,分析PDF布局和对象定位,提取文本,不提供表格提取或可视化调试的工具。
  • PyPDF2是一个纯Python库“能够拆分、合并、裁剪和转换PDF文件的页面。它还可以为PDF文件添加自定义数据、查看选项和密码。”它可以提取页面文本,但不提供对形状对象(矩形、线条等)、表格提取或可视化调试工具的轻松访问。
  • pymupdf大大快于pdfminer.six(因此也pdfplumber),可以生成和修改PDF,但该库需要安装非Python软件(MuPDF)。它也不允许轻松访问形状对象(矩形、线条等),并且不提供表格提取或可视化调试工具。
  • camelottabula-pypdftables都主要关注提取表。在某些情况下,它们可能更适合您尝试提取的特定表。

2024-08-22(四)
一周过得好快

这篇关于pdfplumber - pdf 数据提取的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1098720

相关文章

使用MongoDB进行数据存储的操作流程

《使用MongoDB进行数据存储的操作流程》在现代应用开发中,数据存储是一个至关重要的部分,随着数据量的增大和复杂性的增加,传统的关系型数据库有时难以应对高并发和大数据量的处理需求,MongoDB作为... 目录什么是MongoDB?MongoDB的优势使用MongoDB进行数据存储1. 安装MongoDB

Python MySQL如何通过Binlog获取变更记录恢复数据

《PythonMySQL如何通过Binlog获取变更记录恢复数据》本文介绍了如何使用Python和pymysqlreplication库通过MySQL的二进制日志(Binlog)获取数据库的变更记录... 目录python mysql通过Binlog获取变更记录恢复数据1.安装pymysqlreplicat

Linux使用dd命令来复制和转换数据的操作方法

《Linux使用dd命令来复制和转换数据的操作方法》Linux中的dd命令是一个功能强大的数据复制和转换实用程序,它以较低级别运行,通常用于创建可启动的USB驱动器、克隆磁盘和生成随机数据等任务,本文... 目录简介功能和能力语法常用选项示例用法基础用法创建可启动www.chinasem.cn的 USB 驱动

python实现pdf转word和excel的示例代码

《python实现pdf转word和excel的示例代码》本文主要介绍了python实现pdf转word和excel的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价... 目录一、引言二、python编程1,PDF转Word2,PDF转Excel三、前端页面效果展示总结一

Oracle数据库使用 listagg去重删除重复数据的方法汇总

《Oracle数据库使用listagg去重删除重复数据的方法汇总》文章介绍了在Oracle数据库中使用LISTAGG和XMLAGG函数进行字符串聚合并去重的方法,包括去重聚合、使用XML解析和CLO... 目录案例表第一种:使用wm_concat() + distinct去重聚合第二种:使用listagg,

基于C#实现PDF文件合并工具

《基于C#实现PDF文件合并工具》这篇文章主要为大家详细介绍了如何基于C#实现一个简单的PDF文件合并工具,文中的示例代码简洁易懂,有需要的小伙伴可以跟随小编一起学习一下... 界面主要用于发票PDF文件的合并。经常出差要报销的很有用。代码using System;using System.Col

Java后端接口中提取请求头中的Cookie和Token的方法

《Java后端接口中提取请求头中的Cookie和Token的方法》在现代Web开发中,HTTP请求头(Header)是客户端与服务器之间传递信息的重要方式之一,本文将详细介绍如何在Java后端(以Sp... 目录引言1. 背景1.1 什么是 HTTP 请求头?1.2 为什么需要提取请求头?2. 使用 Spr

Python实现将实体类列表数据导出到Excel文件

《Python实现将实体类列表数据导出到Excel文件》在数据处理和报告生成中,将实体类的列表数据导出到Excel文件是一项常见任务,Python提供了多种库来实现这一目标,下面就来跟随小编一起学习一... 目录一、环境准备二、定义实体类三、创建实体类列表四、将实体类列表转换为DataFrame五、导出Da

Java操作PDF文件实现签订电子合同详细教程

《Java操作PDF文件实现签订电子合同详细教程》:本文主要介绍如何在PDF中加入电子签章与电子签名的过程,包括编写Word文件、生成PDF、为PDF格式做表单、为表单赋值、生成文档以及上传到OB... 目录前言:先看效果:1.编写word文件1.2然后生成PDF格式进行保存1.3我这里是将文件保存到本地后

Python实现数据清洗的18种方法

《Python实现数据清洗的18种方法》本文主要介绍了Python实现数据清洗的18种方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学... 目录1. 去除字符串两边空格2. 转换数据类型3. 大小写转换4. 移除列表中的重复元素5. 快速统