查看 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
都主要專注於提取表格。在某些情況下,它們可能更適合您嘗試提取的特定表。
非常感謝以下用戶提供的想法、功能和修復:
歡迎請求請求,但請先提交提案問題,因為該庫正在積極開發中。
目前維護者: