Temukan PDF untuk informasi mendetail tentang setiap karakter teks, persegi panjang, dan garis. Plus: Ekstraksi tabel dan debugging visual.
Berfungsi paling baik pada PDF yang dihasilkan mesin, bukan dipindai. Dibangun di pdfminer.six
.
Saat ini diuji pada Python 3.8, 3.9, 3.10, 3.11.
Terjemahan dokumen ini tersedia dalam: Mandarin (oleh @hbh112233abc).
Untuk melaporkan bug atau meminta fitur, silakan ajukan masalah. Untuk mengajukan pertanyaan atau meminta bantuan dengan PDF tertentu, silakan gunakan forum diskusi.
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
Outputnya akan berupa CSV yang berisi info tentang setiap karakter, garis, dan persegi panjang di PDF.
Argumen | Keterangan |
---|---|
--format [format] | csv atau json . Format json mengembalikan lebih banyak informasi; itu mencakup metadata tingkat PDF dan tingkat halaman, ditambah atribut bersarang kamus. |
--pages [list of pages] | Daftar halaman yang dibatasi spasi dan diindeks 1 atau rentang halaman yang diberi tanda hubung. Misalnya, 1, 11-15 , yang akan mengembalikan data untuk halaman 1, 11, 12, 13, 14, dan 15. |
--types [list of object types to extract] | Pilihannya adalah char , rect , line , curve , image , annot , dan lain-lain. Default untuk semua tersedia. |
--laparams | String berformat JSON (misalnya, '{"detect_vertical": true}' ) untuk diteruskan ke pdfplumber.open(..., laparams=...) . |
--precision [integer] | Jumlah tempat desimal untuk membulatkan angka floating-point. Defaultnya adalah tidak ada pembulatan. |
import pdfplumber
with pdfplumber . open ( "path/to/file.pdf" ) as pdf :
first_page = pdf . pages [ 0 ]
print ( first_page . chars [ 0 ])
Untuk mulai bekerja dengan PDF, hubungi pdfplumber.open(x)
, di mana x
dapat berupa:
Metode open
mengembalikan sebuah instance dari kelas pdfplumber.PDF
.
Untuk memuat PDF yang dilindungi kata sandi, berikan argumen kata kunci password
, misalnya pdfplumber.open("file.pdf", password = "test")
.
Untuk menyetel parameter analisis tata letak ke mesin tata letak pdfminer.six
, berikan argumen kata kunci laparams
, misalnya, pdfplumber.open("file.pdf", laparams = { "line_overlap": 0.7 })
.
Untuk melakukan pra-normalisasi teks Unicode, teruskan unicode_norm=...
, di mana ...
adalah salah satu dari empat bentuk normalisasi Unicode: "NFC"
, "NFD"
, "NFKC"
, atau "NFKD"
.
Nilai metadata yang tidak valid diperlakukan sebagai peringatan secara default. Jika hal tersebut tidak dimaksudkan, teruskan strict_metadata=True
ke metode open
dan pdfplumber.open
akan memunculkan pengecualian jika tidak dapat mengurai metadata.
pdfplumber.PDF
Kelas pdfplumber.PDF
tingkat atas mewakili satu PDF dan memiliki dua properti utama:
Milik | Keterangan |
---|---|
.metadata | Kamus pasangan kunci/nilai metadata, diambil dari cuplikan Info PDF. Biasanya mencakup "CreationDate", "ModDate", "Producer", dan lain-lain. |
.pages | Daftar yang berisi satu contoh pdfplumber.Page per halaman dimuat. |
... dan juga memiliki metode berikut:
Metode | Keterangan |
---|---|
.close() | Memanggil metode ini akan memanggil Page.close() pada setiap halaman, dan juga menutup aliran file (kecuali jika aliran tersebut bersifat eksternal, yaitu sudah dibuka dan diteruskan langsung ke pdfplumber ). |
pdfplumber.Page
Kelas pdfplumber.Page
adalah inti dari pdfplumber
. Kebanyakan hal yang akan Anda lakukan dengan pdfplumber
akan berkisar pada kelas ini. Ia memiliki sifat-sifat utama berikut:
Milik | Keterangan |
---|---|
.page_number | Nomor halamannya berurutan, dimulai dari 1 untuk halaman pertama, 2 untuk halaman kedua, dan seterusnya. |
.width | Lebar halaman. |
.height | Tinggi halaman. |
.objects / .chars / .lines / .rects / .curves / .images | Masing-masing properti ini adalah sebuah daftar, dan setiap daftar berisi satu kamus untuk setiap objek yang disematkan pada halaman. Untuk lebih jelasnya, lihat "Objek" di bawah. |
... dan metode utama ini:
Metode | Keterangan |
---|---|
.crop(bounding_box, relative=False, strict=True) | Mengembalikan versi halaman yang dipotong ke kotak pembatas, yang harus dinyatakan sebagai 4 tuple dengan nilai (x0, top, x1, bottom) . Halaman yang dipotong mempertahankan objek yang setidaknya sebagian berada di dalam kotak pembatas. Jika suatu benda hanya jatuh sebagian di dalam kotak, dimensinya dipotong agar sesuai dengan kotak pembatas. Jika relative=True , kotak pembatas dihitung sebagai offset dari kiri atas kotak pembatas halaman, bukan posisi absolut. (Lihat Edisi #245 untuk contoh visual dan penjelasannya.) Jika strict=True (default), kotak pembatas pemotongan harus seluruhnya berada dalam kotak pembatas halaman. |
.within_bbox(bounding_box, relative=False, strict=True) | Mirip dengan .crop , tetapi hanya mempertahankan objek yang seluruhnya berada dalam kotak pembatas. |
.outside_bbox(bounding_box, relative=False, strict=True) | Mirip dengan .crop dan .within_bbox , tetapi hanya mempertahankan objek yang seluruhnya berada di luar kotak pembatas. |
.filter(test_function) | Mengembalikan versi halaman dengan hanya .objects yang test_function(obj) mengembalikan True . |
... dan juga memiliki metode berikut:
Metode | Keterangan |
---|---|
.close() | Secara default, objek Page menyimpan tata letak dan informasi objeknya dalam cache agar tidak perlu memprosesnya ulang. Namun, saat menguraikan PDF berukuran besar, properti yang di-cache ini memerlukan banyak memori. Anda dapat menggunakan metode ini untuk membersihkan cache dan melepaskan memori. |
Metode tambahan dijelaskan pada bagian di bawah ini:
Setiap contoh pdfplumber.PDF
dan pdfplumber.Page
menyediakan akses ke beberapa jenis objek PDF, semuanya berasal dari penguraian PDF pdfminer.six
. Properti berikut masing-masing mengembalikan daftar objek yang cocok dengan Python:
.chars
, masing-masing mewakili satu karakter teks..lines
, masing-masing mewakili satu garis 1 dimensi..rects
, masing-masing mewakili satu persegi panjang 2 dimensi..curves
, masing-masing mewakili serangkaian titik terhubung yang tidak dikenali pdfminer.six
sebagai garis atau persegi panjang..images
, masing-masing mewakili gambar..annots
, masing-masing mewakili satu anotasi PDF (lihat Bagian 8.4 dari spesifikasi PDF resmi untuk detailnya).hyperlinks
, masing-masing mewakili satu anotasi PDF dari subtipe Link
dan memiliki atribut tindakan URI
Setiap objek direpresentasikan sebagai dict
Python sederhana, dengan properti berikut:
char
Milik | Keterangan |
---|---|
page_number | Nomor halaman tempat karakter ini ditemukan. |
text | Misalnya, "z", atau "Z" atau " ". |
fontname | Nama font wajah karakter. |
size | Ukuran huruf. |
adv | Sama dengan lebar teks * ukuran font * faktor skala. |
upright | Apakah karakternya jujur. |
height | Ketinggian karakter. |
width | Lebar karakter. |
x0 | Jarak sisi kiri karakter dari sisi kiri halaman. |
x1 | Jarak sisi kanan karakter dari sisi kiri halaman. |
y0 | Jarak bagian bawah karakter dari bagian bawah halaman. |
y1 | Jarak bagian atas karakter dari bagian bawah halaman. |
top | Jarak bagian atas karakter dari bagian atas halaman. |
bottom | Jarak bagian bawah karakter dari bagian atas halaman. |
doctop | Jarak bagian atas karakter dari bagian atas dokumen. |
matrix | "Matriks transformasi saat ini" untuk karakter ini. (Lihat di bawah untuk detailnya.) |
mcid | ID bagian konten yang ditandai untuk karakter ini jika ada (jika tidak, None ). Atribut eksperimental. |
tag | Tag bagian konten yang ditandai untuk karakter ini jika ada (jika tidak, None ). Atribut eksperimental. |
ncs | TKTK |
stroking_pattern | TKTK |
non_stroking_pattern | TKTK |
stroking_color | Warna garis luar karakter (yaitu guratan). Lihat docs/colors.md untuk detailnya. |
non_stroking_color | Warna interior karakter. Lihat docs/colors.md untuk detailnya. |
object_type | "arang" |
Catatan : Properti matrix
karakter mewakili “matriks transformasi saat ini,” seperti yang dijelaskan dalam Bagian 4.2.2 Referensi PDF (Edisi ke-6). Matriks mengontrol skala karakter, kemiringan, dan terjemahan posisi. Rotasi merupakan kombinasi skala dan kemiringan, namun dalam banyak kasus dapat dianggap sama dengan kemiringan sumbu x. Submodul pdfplumber.ctm
mendefinisikan kelas, CTM
, yang membantu penghitungan ini. Misalnya:
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
Milik | Keterangan |
---|---|
page_number | Nomor halaman tempat baris ini ditemukan. |
height | Ketinggian garis. |
width | Lebar garis. |
x0 | Jarak ekstremitas sisi kiri dari sisi kiri halaman. |
x1 | Jarak ekstremitas sisi kanan dari sisi kiri halaman. |
y0 | Jarak ujung bawah dari bawah halaman. |
y1 | Jarak ekstremitas atas bagian bawah halaman. |
top | Jarak bagian atas baris dari bagian atas halaman. |
bottom | Jarak baris terbawah dari atas halaman. |
doctop | Jarak bagian atas baris dari bagian atas dokumen. |
linewidth | Ketebalan garis. |
stroking_color | Warna garis. Lihat docs/colors.md untuk detailnya. |
non_stroking_color | Warna non-goresan yang ditentukan untuk jalur garis. Lihat docs/colors.md untuk detailnya. |
mcid | ID bagian konten yang ditandai untuk baris ini jika ada (jika tidak, None ). Atribut eksperimental. |
tag | Tag bagian konten yang ditandai untuk baris ini jika ada (jika tidak, None ). Atribut eksperimental. |
object_type | "garis" |
rect
Milik | Keterangan |
---|---|
page_number | Nomor halaman tempat persegi panjang ini ditemukan. |
height | Tinggi persegi panjang. |
width | Lebar persegi panjang. |
x0 | Jarak sisi kiri persegi panjang dari sisi kiri halaman. |
x1 | Jarak sisi kanan persegi panjang dari sisi kiri halaman. |
y0 | Jarak bagian bawah persegi panjang dari bagian bawah halaman. |
y1 | Jarak bagian atas persegi panjang dari bagian bawah halaman. |
top | Jarak bagian atas persegi panjang dari bagian atas halaman. |
bottom | Jarak bagian bawah persegi panjang dari bagian atas halaman. |
doctop | Jarak bagian atas persegi panjang dari bagian atas dokumen. |
linewidth | Ketebalan garis. |
stroking_color | Warna garis luar persegi panjang. Lihat docs/colors.md untuk detailnya. |
non_stroking_color | Warna isian persegi panjang. Lihat docs/colors.md untuk detailnya. |
mcid | ID bagian konten yang ditandai untuk kotak ini jika ada (jika tidak, None ). Atribut eksperimental. |
tag | Tag bagian konten yang ditandai untuk kotak ini jika ada (jika tidak, None ). Atribut eksperimental. |
object_type | "benar" |
curve
Milik | Keterangan |
---|---|
page_number | Nomor halaman tempat kurva ini ditemukan. |
pts | Daftar tupel (x, top) yang menunjukkan titik-titik pada kurva . |
path | Daftar tupel (cmd, *(x, top)) yang menjelaskan deskripsi jalur lengkap , termasuk (misalnya) titik kontrol yang digunakan dalam kurva Bezier. |
height | Ketinggian kotak pembatas kurva. |
width | Lebar kotak pembatas kurva. |
x0 | Jarak titik paling kiri kurva dari sisi kiri halaman. |
x1 | Jarak titik paling kanan kurva dari sisi kiri halaman. |
y0 | Jarak titik terendah kurva dari bawah halaman. |
y1 | Jarak titik tertinggi kurva dari bawah halaman. |
top | Jarak titik tertinggi kurva dari atas halaman. |
bottom | Jarak titik terendah kurva dari atas halaman. |
doctop | Jarak titik tertinggi kurva dari atas dokumen. |
linewidth | Ketebalan garis. |
fill | Apakah bentuk yang ditentukan oleh jalur kurva terisi. |
stroking_color | Warna garis kurva. Lihat docs/colors.md untuk detailnya. |
non_stroking_color | Warna isian kurva. Lihat docs/colors.md untuk detailnya. |
dash | Tupel ([dash_array], dash_phase) yang menjelaskan gaya garis putus-putus kurva. Lihat Tabel 4.6 spesifikasi PDF untuk rinciannya. |
mcid | ID bagian konten yang ditandai untuk kurva ini jika ada (jika tidak, None ). Atribut eksperimental. |
tag | Tag bagian konten yang ditandai untuk kurva ini jika ada (jika tidak, None ). Atribut eksperimental. |
object_type | "melengkung" |
Selain itu, pdfplumber.PDF
dan pdfplumber.Page
menyediakan akses ke beberapa daftar objek turunan: .rect_edges
(yang menguraikan setiap persegi panjang menjadi empat barisnya), .curve_edges
(yang melakukan hal yang sama untuk objek curve
), dan .edges
(yang menggabungkan .rect_edges
, .curve_edges
, dan .lines
).
image
Catatan: Meskipun posisi dan karakteristik objek image
tersedia melalui pdfplumber
, perpustakaan ini tidak menyediakan dukungan langsung untuk merekonstruksi konten gambar. Untuk itu, silakan lihat saran ini.
Milik | Keterangan |
---|---|
page_number | Nomor halaman tempat gambar itu ditemukan. |
height | Ketinggian gambar. |
width | Lebar gambar. |
x0 | Jarak sisi kiri gambar dari sisi kiri halaman. |
x1 | Jarak sisi kanan gambar dari sisi kiri halaman. |
y0 | Jarak bagian bawah gambar dari bagian bawah halaman. |
y1 | Jarak bagian atas gambar dari bagian bawah halaman. |
top | Jarak bagian atas gambar dari bagian atas halaman. |
bottom | Jarak bagian bawah gambar dari bagian atas halaman. |
doctop | Jarak bagian atas persegi panjang dari bagian atas dokumen. |
srcsize | Dimensi gambar asli, sebagai tupel (width, height) . |
colorspace | Domain warna gambar (misalnya RGB). |
bits | Jumlah bit per komponen warna; misalnya, 8 berhubungan dengan 255 nilai yang mungkin untuk setiap komponen warna (R, G, dan B dalam ruang warna RGB). |
stream | Nilai piksel gambar, sebagai objek pdfminer.pdftypes.PDFStream . |
imagemask | Boolean yang dapat dibatalkan; jika True , "menetapkan bahwa data gambar akan digunakan sebagai topeng stensil untuk melukis dengan warna saat ini." |
mcid | ID bagian konten yang ditandai untuk gambar ini jika ada (jika tidak, None ). Atribut eksperimental. |
tag | Tag bagian konten yang ditandai untuk gambar ini jika ada (jika tidak, None ). Atribut eksperimental. |
object_type | "gambar" |
pdfminer.six
Jika Anda meneruskan parameter pdfminer.six
-handling laparams
ke pdfplumber.open(...)
, maka kamus .objects
setiap halaman juga akan berisi objek tata letak tingkat tinggi pdfminer.six
, seperti "textboxhorizontal"
.
Alat debugging visual pdfplumber
dapat membantu dalam memahami struktur PDF dan objek yang telah diekstraksi darinya.
PageImage
dengan .to_image()
Untuk mengubah halaman mana pun (termasuk halaman yang dipotong) menjadi objek PageImage
, panggil my_page.to_image()
. Anda juga dapat meneruskan salah satu argumen kata kunci berikut:
resolution
: Jumlah piksel per inci yang diinginkan. Bawaan: 72
. Ketik: int
.width
: Lebar gambar yang diinginkan dalam piksel. Default: tidak disetel, ditentukan oleh resolution
. Ketik: int
.height
: Lebar gambar yang diinginkan dalam piksel. Default: tidak disetel, ditentukan oleh resolution
. Ketik: int
.antialias
: Apakah akan menggunakan antialiasing saat membuat gambar. Menyetel ke True
akan menghasilkan gambar dengan teks dan grafik yang tidak terlalu bergerigi, namun dengan ukuran file yang lebih besar. Bawaan: False
. Jenis: bool
.force_mediabox
: Gunakan dimensi .mediabox
laman, bukan dimensi .cropbox
. Bawaan: False
. Jenis: bool
.Misalnya:
im = my_pdf . pages [ 0 ]. to_image ( resolution = 150 )
Dari skrip atau REPL, im.show()
akan membuka gambar di penampil gambar lokal Anda. Namun objek PageImage
juga berfungsi baik dengan notebook Jupyter; mereka secara otomatis dirender sebagai keluaran sel. Misalnya:
Catatan : .to_image(...)
berfungsi seperti yang diharapkan dengan instance Page.crop(...)
/ CroppedPage
, tetapi tidak dapat menggabungkan perubahan yang dibuat melalui instance Page.filter(...)
/ FilteredPage
.
PageImage
Metode | Keterangan |
---|---|
im.reset() | Menghapus apa pun yang telah Anda gambar sejauh ini. |
im.copy() | Menyalin gambar ke objek PageImage baru. |
im.show() | Membuka gambar di penampil gambar lokal Anda. |
im.save(path_or_fileobject, format="PNG", quantize=True, colors=256, bits=8) | Menyimpan gambar beranotasi sebagai file PNG. Argumen default mengkuantisasi gambar ke palet 256 warna, menyimpan PNG dengan kedalaman warna 8-bit. Anda dapat menonaktifkan kuantisasi dengan meneruskan quantize=False atau menyesuaikan ukuran palet warna dengan meneruskan colors=N . |
Anda dapat meneruskan koordinat eksplisit atau objek PDF pdfplumber
apa pun (misalnya, char, garis, persegi) ke metode ini.
Metode objek tunggal | Metode massal | Keterangan |
---|---|---|
im.draw_line(line, stroke={color}, stroke_width=1) | im.draw_lines(list_of_lines, **kwargs) | Menggambar garis dari sebuah line , curve , atau 2-tupel dari 2-tupel (misalnya, ((x, y), (x, y)) ). |
im.draw_vline(location, stroke={color}, stroke_width=1) | im.draw_vlines(list_of_locations, **kwargs) | Menggambar garis vertikal pada koordinat x yang ditunjukkan oleh location . |
im.draw_hline(location, stroke={color}, stroke_width=1) | im.draw_hlines(list_of_locations, **kwargs) | Menggambar garis horizontal pada koordinat y yang ditunjukkan oleh location . |
im.draw_rect(bbox_or_obj, fill={color}, stroke={color}, stroke_width=1) | im.draw_rects(list_of_rects, **kwargs) | Menggambar persegi panjang dari kotak pembatas rect , char , dll., atau 4 tupel. |
im.draw_circle(center_or_obj, radius=5, fill={color}, stroke={color}) | im.draw_circles(list_of_circles, **kwargs) | Menggambar lingkaran pada koordinat (x, y) atau di pusat char , rect , dan seterusnya. |
Catatan: Metode di atas dibuat berdasarkan metode ImageDraw
Pillow, tetapi parameternya telah diubah agar konsisten dengan nomenklatur fill
/ stroke
/ stroke_width
SVG.
im.debug_tablefinder(table_settings={})
akan mengembalikan versi PageImage dengan garis terdeteksi (berwarna merah), persimpangan (lingkaran), dan tabel (biru muda) dilapis.
pdfplumber
dapat mengekstrak teks dari halaman mana pun (termasuk halaman yang dipotong dan diturunkan). Ia juga dapat mencoba mempertahankan tata letak teks tersebut, serta mengidentifikasi koordinat kata dan kueri penelusuran. Objek Page
dapat memanggil metode ekstraksi teks berikut:
Metode | Keterangan |
---|---|
.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) | Menyusun semua objek karakter halaman menjadi satu string.
|
.extract_text_simple(x_tolerance=3, y_tolerance=3) | Versi .extract_text(...) yang sedikit lebih cepat namun kurang fleksibel, menggunakan logika yang lebih sederhana. |
.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) | Mengembalikan daftar semua hal yang tampak seperti kata dan kotak pembatasnya. Kata-kata dianggap sebagai rangkaian karakter yang (untuk karakter "tegak") perbedaan antara x1 dari satu karakter dan x0 dari karakter berikutnya kurang dari atau sama dengan x_tolerance dan di mana doctop dari satu karakter dan doctop dari karakter berikutnya kurang dari atau sama dengan y_tolerance . (Jika x_tolerance_ratio bukan None , ekstraktor menggunakan x_tolerance dinamis yang sama dengan x_tolerance_ratio * previous_character["size"] .) Pendekatan serupa dilakukan untuk karakter tidak tegak, tetapi mengukur jarak vertikal, bukan horizontal, di antara karakter tersebut. Mengubah keep_blank_chars menjadi True berarti karakter kosong diperlakukan sebagai bagian dari kata, bukan sebagai spasi antar kata. Mengubah use_text_flow ke True akan menggunakan aliran karakter yang mendasari PDF sebagai panduan untuk mengurutkan dan mengelompokkan kata, daripada mengurutkan karakter berdasarkan posisi x/y. (Ini meniru cara menyeret kursor menyorot teks dalam PDF; karena itu, urutannya tidak selalu tampak logis.) Argumen line_dir dan char_dir memberi tahu metode ini arah pembacaan baris/karakter; pilihan yang valid adalah "ttb" (atas ke bawah), "btt" (bawah ke atas), "ltr" (kiri ke kanan), dan "rtl" (kanan ke kiri). Argumen line_dir_rotated dan char_dir_rotated serupa, tetapi untuk teks yang telah diputar. Melewati daftar extra_attrs (misalnya, ["fontname", "size"] akan membatasi setiap kata menjadi karakter yang memiliki nilai yang sama persis untuk setiap atribut tersebut, dan dicts kata yang dihasilkan akan menunjukkan atribut tersebut. Menyetel split_at_punctuation ke True akan menerapkan pemutusan token pada tanda baca yang ditentukan oleh string.punctuation ; atau Anda dapat menentukan daftar tanda baca pemisah dengan melewatkan sebuah string, misalnya, split_at_punctuation='!"&'()*+,.:;<=>?@[]^`{|}~' . Kecuali Anda menyetel expand_ligatures=False , pengikat seperti fi akan diperluas ke huruf penyusunnya (misalnya , fi ). Melewati return_chars=True akan menambahkan, ke setiap kamus kata, daftar karakter penyusunnya, sebagai daftar di bidang "chars" . |
.extract_text_lines(layout=False, strip=True, return_chars=True, **kwargs) | Fitur eksperimental yang mengembalikan daftar kamus yang mewakili baris teks pada halaman. Parameter strip bekerja secara analog dengan metode str.strip() Python, dan mengembalikan atribut text tanpa spasi di sekitarnya. (Hanya relevan jika layout = True .) Menyetel return_chars ke False akan mengecualikan objek karakter individual dari dicts baris teks yang dikembalikan. **kwargs yang tersisa adalah yang akan Anda teruskan ke .extract_text(layout=True, ...) . |
.search(pattern, regex=True, case=True, main_group=0, return_groups=True, return_chars=True, layout=False, **kwargs) | Fitur eksperimental yang memungkinkan Anda mencari teks halaman, mengembalikan daftar semua kejadian yang cocok dengan kueri. Untuk setiap instance, objek kamus respons berisi teks yang cocok, grup regex apa pun yang cocok, koordinat kotak pembatas, dan objek char itu sendiri. pattern dapat berupa ekspresi reguler yang dikompilasi, ekspresi reguler yang tidak dikompilasi, atau string non-regex. Jika regex adalah False , polanya diperlakukan sebagai string non-regex. Jika case adalah False , pencarian dilakukan dengan cara yang tidak peka huruf besar-kecil. Pengaturan main_group membatasi hasil ke grup regex tertentu dalam pattern (default 0 berarti keseluruhan kecocokan). Menyetel return_groups dan/atau return_chars ke False akan mengecualikan daftar grup regex dan/atau karakter yang cocok agar tidak ditambahkan (sebagai "groups" dan "chars" pada dicts yang dikembalikan). Parameter layout beroperasi seperti halnya untuk .extract_text(...) . **kwargs yang tersisa adalah yang akan Anda teruskan ke .extract_text(layout=True, ...) . Catatan : Pencocokan dengan lebar nol dan spasi kosong akan dibuang, karena (umumnya) tidak memiliki posisi eksplisit pada halaman. |
.dedupe_chars(tolerance=1, extra_attrs=("fontname", "size")) | Mengembalikan versi halaman dengan karakter duplikat — karakter yang berbagi teks, posisi (dalam tolerance x/y), dan extra_attrs yang sama dengan karakter lain — dihapus. (Lihat Edisi #71 untuk memahami motivasinya.) |
Pendekatan pdfplumber
terhadap deteksi tabel banyak meminjam dari tesis master Anssi Nurminen, dan terinspirasi oleh Tabula. Cara kerjanya seperti ini:
Objek pdfplumber.Page
dapat memanggil metode tabel berikut:
Metode | Keterangan |
---|---|
.find_tables(table_settings={}) | Mengembalikan daftar objek Table . Objek Table menyediakan akses ke properti .cells , .rows , .columns , dan .bbox , serta metode .extract(x_tolerance=3, y_tolerance=3) . |
.find_table(table_settings={}) | Mirip dengan .find_tables(...) , tetapi mengembalikan tabel terbesar pada halaman, sebagai objek Table . Jika beberapa tabel memiliki ukuran yang sama — yang diukur dengan jumlah sel — metode ini mengembalikan tabel yang paling dekat dengan bagian atas halaman. |
.extract_tables(table_settings={}) | Mengembalikan teks yang diekstraksi dari semua tabel yang ditemukan di halaman, direpresentasikan sebagai daftar daftar, dengan struktur table -> row -> cell . |
.extract_table(table_settings={}) | Mengembalikan teks yang diekstraksi dari tabel terbesar di halaman (lihat .find_table(...) di atas), direpresentasikan sebagai daftar daftar, dengan struktur row -> cell . |
.debug_tablefinder(table_settings={}) | Mengembalikan instance kelas TableFinder , dengan akses ke properti .edges , .intersections , .cells , dan .tables . |
Misalnya:
pdf = pdfplumber . open ( "path/to/my.pdf" )
page = pdf . pages [ 0 ]
page . extract_table ()
Klik di sini untuk contoh lebih detail.
Secara default, extract_tables
menggunakan garis vertikal dan horizontal halaman (atau tepi persegi panjang) sebagai pemisah sel. Namun metode ini sangat dapat dikustomisasi melalui argumen table_settings
. Kemungkinan pengaturan dan defaultnya:
{
"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
}
Pengaturan | Keterangan |
---|---|
"vertical_strategy" | Entah "lines" , "lines_strict" , "text" , atau "explicit" . Lihat penjelasannya di bawah ini. |
"horizontal_strategy" | Entah "lines" , "lines_strict" , "text" , atau "explicit" . Lihat penjelasannya di bawah ini. |
"explicit_vertical_lines" | Daftar garis vertikal yang secara eksplisit membatasi sel dalam tabel. Dapat digunakan dalam kombinasi dengan salah satu strategi di atas. Item dalam daftar harus berupa angka — yang menunjukkan koordinat x dari garis sepanjang tinggi halaman — atau objek line / rect / curve . |
"explicit_horizontal_lines" | Daftar garis horizontal yang secara eksplisit membatasi sel dalam tabel. Dapat digunakan dalam kombinasi dengan salah satu strategi di atas. Item dalam daftar harus berupa angka — yang menunjukkan koordinat y dari garis sepanjang tinggi halaman — atau objek line / rect / curve . |
"snap_tolerance" , "snap_x_tolerance" , "snap_y_tolerance" | Garis paralel dalam titik snap_tolerance akan "dijepret" ke posisi horizontal atau vertikal yang sama. |
"join_tolerance" , "join_x_tolerance" , "join_y_tolerance" | Ruas garis pada garis tak terhingga yang sama, dan ujung-ujungnya berada dalam join_tolerance satu sama lain, akan "digabung" menjadi satu ruas garis. |
"edge_min_length" | Tepi yang lebih pendek dari edge_min_length akan dibuang sebelum mencoba merekonstruksi tabel. |
"min_words_vertical" | Saat menggunakan "vertical_strategy": "text" , setidaknya kata min_words_vertical harus memiliki keselarasan yang sama. |
"min_words_horizontal" | Saat menggunakan "horizontal_strategy": "text" , setidaknya kata min_words_horizontal harus memiliki keselarasan yang sama. |
"intersection_tolerance" , "intersection_x_tolerance" , "intersection_y_tolerance" | Saat menggabungkan tepi ke dalam sel, tepi ortogonal harus berada dalam titik intersection_tolerance agar dianggap berpotongan. |
"text_*" | Semua pengaturan yang diawali dengan text_ kemudian digunakan saat mengekstraksi teks dari setiap tabel yang ditemukan. Semua kemungkinan argumen untuk Page.extract_text(...) juga valid di sini. |
"text_x_tolerance" , "text_y_tolerance" | Pengaturan text_ -prefixed ini juga berlaku untuk algoritma identifikasi tabel ketika strategi text digunakan. Yaitu, ketika algoritma tersebut mencari kata-kata, maka diharapkan masing-masing huruf dalam setiap kata tidak lebih dari text_x_tolerance / text_y_tolerance poin. |
Baik vertical_strategy
maupun horizontal_strategy
menerima opsi berikut:
Strategi | Keterangan |
---|---|
"lines" | Gunakan garis grafis halaman — termasuk sisi objek persegi panjang — sebagai batas sel tabel potensial. |
"lines_strict" | Gunakan garis grafis halaman — tetapi bukan sisi objek persegi panjang — sebagai batas sel tabel potensial. |
"text" | Untuk vertical_strategy : Simpulkan garis (imajiner) yang menghubungkan kiri, kanan, atau tengah kata pada halaman, dan gunakan garis tersebut sebagai batas sel tabel potensial. Untuk horizontal_strategy , sama tetapi menggunakan kata-kata teratas. |
"explicit" | Hanya gunakan garis yang didefinisikan secara eksplisit dalam explicit_vertical_lines / explicit_horizontal_lines . |
Seringkali berguna untuk memotong halaman — Page.crop(bounding_box)
— sebelum mencoba mengekstrak tabel.
Ekstraksi tabel untuk pdfplumber
didesain ulang secara radikal untuk v0.5.0
, dan memperkenalkan perubahan yang dapat mengganggu.
Terkadang file PDF dapat berisi formulir yang menyertakan masukan yang dapat diisi dan disimpan orang. Meskipun nilai dalam bidang formulir tampak seperti teks lain dalam file PDF, data formulir ditangani secara berbeda. Jika Anda menginginkan detail yang mengerikan, lihat halaman 671 dari spesifikasi ini.
pdfplumber
tidak memiliki antarmuka untuk bekerja dengan data formulir, tetapi Anda dapat mengaksesnya menggunakan pembungkus pdfplumber
di sekitar pdfminer
.
Misalnya, cuplikan ini akan mengambil nama dan nilai bidang formulir dan menyimpannya dalam kamus.
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 )
Setelah Anda menjalankan skrip ini, form_data
adalah daftar yang berisi tupel tiga elemen untuk setiap elemen formulir. Misalnya, formulir PDF dengan kolom kota dan negara bagian mungkin terlihat seperti ini.
[
['STATE.0', 'enter STATE', 'CA'],
['section 2 accident infoRmation.1.0',
'enter city of accident',
'SAN FRANCISCO']
]
Terima kasih kepada @jeremybmerrill yang telah membantu menjaga kode penguraian formulir di atas.
extract_table
pada laporan Penyesuaian dan Pelatihan Ulang Pekerja California (WARN). Mendemonstrasikan debugging visual dasar dan ekstraksi tabel.extract_table
pada PDF Sistem Pemeriksaan Latar Belakang Kriminal Instan Nasional FBI. Menunjukkan cara menggunakan debugging visual untuk menemukan pengaturan ekstraksi tabel yang optimal. Juga mendemonstrasikan Page.crop(...)
dan Page.extract_text(...).
curve
.Page.extract_text(...)
. Beberapa perpustakaan Python lainnya membantu pengguna mengekstrak informasi dari PDF. Sebagai gambaran umum, pdfplumber
membedakan dirinya dari perpustakaan pemrosesan PDF lainnya dengan menggabungkan fitur-fitur berikut:
Mengetahui fitur apa saja yang tidak disediakan oleh pdfplumber
juga bermanfaat:
pdfminer.six
memberikan dasar untuk pdfplumber
. Ini terutama berfokus pada penguraian PDF, menganalisis tata letak PDF dan pemosisian objek, dan mengekstraksi teks. Itu tidak menyediakan alat untuk ekstraksi tabel atau debugging visual.
PyPDF2
adalah perpustakaan Python murni "yang mampu memisahkan, menggabungkan, memotong, dan mengubah halaman file PDF. Ia juga dapat menambahkan data khusus, opsi tampilan, dan kata sandi ke file PDF." Itu dapat mengekstrak teks halaman, tetapi tidak menyediakan akses mudah ke objek bentuk (persegi panjang, garis, dll.), ekstraksi tabel, atau alat debugging visual.
pymupdf
jauh lebih cepat daripada pdfminer.six
(dan juga pdfplumber
) dan dapat menghasilkan dan memodifikasi PDF, tetapi perpustakaan memerlukan instalasi perangkat lunak non-Python (MuPDF). Itu juga tidak memungkinkan akses mudah ke objek bentuk (persegi panjang, garis, dll.), dan tidak menyediakan alat ekstraksi tabel atau debugging visual.
camelot
, tabula-py
, dan pdftables
semuanya fokus terutama pada ekstraksi tabel. Dalam beberapa kasus, tabel tersebut mungkin lebih cocok untuk tabel tertentu yang Anda coba ekstrak.
Terima kasih banyak kepada pengguna berikut yang telah menyumbangkan ide, fitur, dan perbaikan:
Permintaan tarik diperkenankan, tetapi harap kirimkan proposal masalah terlebih dahulu, karena perpustakaan sedang dalam pengembangan aktif.
Pengelola saat ini: