Dưới đây là một ví dụ sẵn sàng sao chép và dán, liệt kê các góc trên cùng bên trái của mỗi khối văn bản trong PDF và tôi nghĩ nên hoạt động cho bất kỳ PDF nào không bao gồm "Mẫu Xobjects" có văn bản trong đó:
from pdfminer.layout import LAParams, LTTextBox from pdfminer.pdfpage import PDFPage from pdfminer.pdfinterp import PDFResourceManager from pdfminer.pdfinterp import PDFPageInterpreter from pdfminer.converter import PDFPageAggregator fp = open('yourpdf.pdf', 'rb') rsrcmgr = PDFResourceManager() laparams = LAParams() device = PDFPageAggregator(rsrcmgr, laparams=laparams) interpreter = PDFPageInterpreter(rsrcmgr, device) pages = PDFPage.get_pages(fp) for page in pages: print('Processing next page...') interpreter.process_page(page) layout = device.get_result() for lobj in layout: if isinstance(lobj, LTTextBox): x, y, text = lobj.bbox[0], lobj.bbox[3], lobj.get_text() print('At %r is text: %s' % ((x, y), text))Mã trên dựa trên ví dụ phân tích bố cục thực hiện trong các tài liệu PDFMiner, cộng với các ví dụ của PNJ (//stackoverflow.com/a/22898159/1709587) và Matt Swain (//stackoverflow.com/a/a/a 25262470/1709587). Có một vài thay đổi tôi đã thực hiện từ các ví dụ trước đây:
- Tôi sử dụng PDFPage.get_pages(), là một tốc ký để tạo tài liệu, kiểm tra nó is_extractable và chuyển nó cho PDFPage.create_pages()
- Tôi không buồn xử lý LTFigures, vì PDFMiner hiện không có khả năng xử lý văn bản sạch sẽ bên trong chúng.
LAParams cho phép bạn đặt một số tham số kiểm soát cách các ký tự riêng lẻ trong PDF được nhóm một cách kỳ diệu thành các dòng và hộp văn bản của PDFMiner. Nếu bạn ngạc nhiên rằng việc nhóm như vậy là một điều cần phải xảy ra, thì đó là hợp lý trong các tài liệu PDF2TXT:
Trong một tệp PDF thực tế, các phần văn bản có thể được chia thành nhiều khối ở giữa hoạt động của nó, tùy thuộc vào phần mềm tác giả. Do đó, trích xuất văn bản cần phải nối các đoạn văn bản.
Các tham số của ________ 6, giống như hầu hết các pdfminer, không có giấy tờ, nhưng bạn có thể thấy chúng trong mã nguồn hoặc bằng cách gọi help(LAParams) tại vỏ Python của bạn. Ý nghĩa của một số tham số được đưa ra tại //pdfminer-docs.readthedocs.io/pdfminer_index.html#pdf2txt-py vì chúng cũng có thể được truyền dưới dạng đối số cho pdf2text tại dòng lệnh.
Đối tượng x0, y0_orig, x1, y1_orig = some_lobj.bbox y0 = page.mediabox[3] - y1_orig y1 = page.mediabox[3] - y0_orig 0 ở trên là một x0, y0_orig, x1, y1_orig = some_lobj.bbox y0 = page.mediabox[3] - y1_orig y1 = page.mediabox[3] - y0_orig 1, là một điều không thể sử dụng được của "các đối tượng bố cục". Mỗi đối tượng bố cục này có thể là một trong các loại sau ...
- x0, y0_orig, x1, y1_orig = some_lobj.bbox y0 = page.mediabox[3] - y1_orig y1 = page.mediabox[3] - y0_orig 2
- LTFigure
- x0, y0_orig, x1, y1_orig = some_lobj.bbox y0 = page.mediabox[3] - y1_orig y1 = page.mediabox[3] - y0_orig 4
- x0, y0_orig, x1, y1_orig = some_lobj.bbox y0 = page.mediabox[3] - y1_orig y1 = page.mediabox[3] - y0_orig 5
- x0, y0_orig, x1, y1_orig = some_lobj.bbox y0 = page.mediabox[3] - y1_orig y1 = page.mediabox[3] - y0_orig 6
... hoặc các lớp con của họ. (Đặc biệt, các hộp văn bản của bạn có thể sẽ là x0, y0_orig, x1, y1_orig = some_lobj.bbox y0 = page.mediabox[3] - y1_orig y1 = page.mediabox[3] - y0_orig 7s.)
Thông tin chi tiết hơn về cấu trúc của x0, y0_orig, x1, y1_orig = some_lobj.bbox y0 = page.mediabox[3] - y1_orig y1 = page.mediabox[3] - y0_orig 1 được hiển thị bằng hình ảnh này từ các tài liệu:
Mỗi loại trên có thuộc tính x0, y0_orig, x1, y1_orig = some_lobj.bbox y0 = page.mediabox[3] - y1_orig y1 = page.mediabox[3] - y0_orig 9 chứa một bộ (x0, y0, x1, y1) chứa tọa độ của bên trái, dưới, bên phải và trên cùng của đối tượng. Các tọa độ y được đưa ra làm khoảng cách từ dưới cùng của trang. Nếu nó thuận tiện hơn để bạn làm việc với trục y đi từ trên xuống dưới, bạn có thể trừ chúng từ độ cao của trang PDFPage.get_pages()0 của trang:
x0, y0_orig, x1, y1_orig = some_lobj.bbox y0 = page.mediabox[3] - y1_orig y1 = page.mediabox[3] - y0_origNgoài PDFPage.get_pages()1, x0, y0_orig, x1, y1_orig = some_lobj.bbox y0 = page.mediabox[3] - y1_orig y1 = page.mediabox[3] - y0_orig 2ES cũng có phương thức PDFPage.get_pages()3, được hiển thị ở trên, trả về nội dung văn bản của chúng dưới dạng chuỗi. Lưu ý rằng mỗi x0, y0_orig, x1, y1_orig = some_lobj.bbox y0 = page.mediabox[3] - y1_orig y1 = page.mediabox[3] - y0_orig 2 là một tập hợp các PDFPage.get_pages()5s (ký tự được vẽ rõ ràng bởi PDF, với PDFPage.get_pages()1) và PDFPage.get_pages()7 (không gian bổ sung mà PDFMiner thêm vào biểu diễn chuỗi của hộp văn bản dựa trên các ký tự được vẽ một cách dài; không có PDFPage.get_pages()1).
Ví dụ mã ở đầu câu trả lời này đã kết hợp hai thuộc tính này để hiển thị tọa độ của từng khối văn bản.
Cuối cùng, điều đáng chú ý là, không giống như các câu trả lời tràn của ngăn xếp khác được trích dẫn ở trên, tôi không bận tâm đến các LTFigures. Mặc dù LTFigure có thể chứa văn bản, PDFMiner dường như không có khả năng nhóm văn bản đó thành x0, y0_orig, x1, y1_orig = some_lobj.bbox y0 = page.mediabox[3] - y1_orig y1 = page.mediabox[3] - y0_orig 2ES (bạn có thể tự thử trên ví dụ PDF từ //stackoverflow.com/a/27104504/1709587) và thay vào đó PDFPage.get_pages()5 Đối tượng. Về nguyên tắc, bạn có thể tìm ra cách ghép chúng lại thành một chuỗi, nhưng pdfminer (kể từ phiên bản 20181108) không thể làm điều đó cho bạn.
Mặc dù vậy, hy vọng, các tệp PDF bạn cần phân tích không sử dụng XOBjects với văn bản trong đó, và vì vậy sự cảnh báo này sẽ không áp dụng cho bạn.