Mô-đun Python để chuyển đổi PDF thành văn bản [đã đóng]


385

Có mô-đun python nào để chuyển đổi tập tin PDF thành văn bản không? Tôi đã thử một đoạn mã được tìm thấy trong Activestate sử dụng pypdf nhưng văn bản được tạo ra không có khoảng cách giữa và không sử dụng được.


1
Tôi đã tìm kiếm giải pháp tương tự. Tôi chỉ cần đọc văn bản từ tập tin pdf. Tôi không cần những hình ảnh. pdfminer là một lựa chọn tốt nhưng tôi đã không tìm thấy một ví dụ đơn giản về cách trích xuất văn bản. Cuối cùng tôi đã nhận được câu trả lời SO này ( stackoverflow.com/questions/5725278/ cấp ) và bây giờ sử dụng nó.
Naya

2
Vì câu hỏi đã bị đóng, tôi đã đăng lại nó trên Stack Exchange dành riêng cho các đề xuất phần mềm trong trường hợp ai đó muốn viết câu trả lời mới: Mô-đun Python để chuyển đổi PDF thành văn bản
Franck Dernoncourt

1
Giải pháp duy nhất phù hợp với tôi cho nội dung UTF-8: Apache Tika
Shoham

Tôi muốn cập nhật danh sách tùy chọn khả dụng cho chuyển đổi PDF sang Văn bản trong Python, GroupDocs.Conversion Cloud SDK cho Python chuyển đổi PDF thành văn bản một cách chính xác.
Tilal Ahmad

Câu trả lời:


142

Hãy thử PDFMiner . Nó có thể trích xuất văn bản từ các tệp PDF dưới dạng HTML, SGML hoặc định dạng "Tagged PDF".

Định dạng PDF được gắn thẻ có vẻ là sạch nhất và việc loại bỏ các thẻ XML chỉ để lại văn bản trống.

Phiên bản Python 3 có sẵn trong:


2
Tôi vừa thêm một câu trả lời giải thích cách sử dụng pdfminer làm thư viện.
codeape

24
không hỗ trợ python 3 :(
Karl Adler

1
Câu trả lời tôi cung cấp trong chủ đề này có thể hữu ích cho những người nhìn vào câu trả lời này và tự hỏi làm thế nào để sử dụng thư viện. Tôi đưa ra một ví dụ về cách sử dụng thư viện PDFMiner để trích xuất văn bản từ PDF. Vì tài liệu này hơi thưa thớt, tôi nghĩ rằng nó có thể giúp một vài người.
DuckPuncher

17
liên quan đến python 3, có một ngã ba pypi.python.org/pypi/pdfminer.six
Denis Cornehl


136

Các PDFMiner gói đã thay đổi kể từ codeape đăng.

EDIT (một lần nữa):

PDFMiner đã được cập nhật lại trong phiên bản 20100213

Bạn có thể kiểm tra phiên bản bạn đã cài đặt như sau:

>>> import pdfminer
>>> pdfminer.__version__
'20100213'

Đây là phiên bản cập nhật (có nhận xét về những gì tôi đã thay đổi / thêm):

def pdf_to_csv(filename):
    from cStringIO import StringIO  #<-- added so you can copy/paste this to try it
    from pdfminer.converter import LTTextItem, TextConverter
    from pdfminer.pdfparser import PDFDocument, PDFParser
    from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter

    class CsvConverter(TextConverter):
        def __init__(self, *args, **kwargs):
            TextConverter.__init__(self, *args, **kwargs)

        def end_page(self, i):
            from collections import defaultdict
            lines = defaultdict(lambda : {})
            for child in self.cur_item.objs:
                if isinstance(child, LTTextItem):
                    (_,_,x,y) = child.bbox                   #<-- changed
                    line = lines[int(-y)]
                    line[x] = child.text.encode(self.codec)  #<-- changed

            for y in sorted(lines.keys()):
                line = lines[y]
                self.outfp.write(";".join(line[x] for x in sorted(line.keys())))
                self.outfp.write("\n")

    # ... the following part of the code is a remix of the 
    # convert() function in the pdfminer/tools/pdf2text module
    rsrc = PDFResourceManager()
    outfp = StringIO()
    device = CsvConverter(rsrc, outfp, codec="utf-8")  #<-- changed 
        # becuase my test documents are utf-8 (note: utf-8 is the default codec)

    doc = PDFDocument()
    fp = open(filename, 'rb')
    parser = PDFParser(fp)       #<-- changed
    parser.set_document(doc)     #<-- added
    doc.set_parser(parser)       #<-- added
    doc.initialize('')

    interpreter = PDFPageInterpreter(rsrc, device)

    for i, page in enumerate(doc.get_pages()):
        outfp.write("START PAGE %d\n" % i)
        interpreter.process_page(page)
        outfp.write("END PAGE %d\n" % i)

    device.close()
    fp.close()

    return outfp.getvalue()

Chỉnh sửa (một lần nữa):

Đây là bản cập nhật cho phiên bản mới nhất bằng pypi , 20100619p1. Nói tóm lại tôi đã thay thế LTTextItemvới LTCharvà thông qua một thể hiện của LAParams để các nhà xây dựng CsvConverter.

def pdf_to_csv(filename):
    from cStringIO import StringIO  
    from pdfminer.converter import LTChar, TextConverter    #<-- changed
    from pdfminer.layout import LAParams
    from pdfminer.pdfparser import PDFDocument, PDFParser
    from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter

    class CsvConverter(TextConverter):
        def __init__(self, *args, **kwargs):
            TextConverter.__init__(self, *args, **kwargs)

        def end_page(self, i):
            from collections import defaultdict
            lines = defaultdict(lambda : {})
            for child in self.cur_item.objs:
                if isinstance(child, LTChar):               #<-- changed
                    (_,_,x,y) = child.bbox                   
                    line = lines[int(-y)]
                    line[x] = child.text.encode(self.codec)

            for y in sorted(lines.keys()):
                line = lines[y]
                self.outfp.write(";".join(line[x] for x in sorted(line.keys())))
                self.outfp.write("\n")

    # ... the following part of the code is a remix of the 
    # convert() function in the pdfminer/tools/pdf2text module
    rsrc = PDFResourceManager()
    outfp = StringIO()
    device = CsvConverter(rsrc, outfp, codec="utf-8", laparams=LAParams())  #<-- changed
        # becuase my test documents are utf-8 (note: utf-8 is the default codec)

    doc = PDFDocument()
    fp = open(filename, 'rb')
    parser = PDFParser(fp)       
    parser.set_document(doc)     
    doc.set_parser(parser)       
    doc.initialize('')

    interpreter = PDFPageInterpreter(rsrc, device)

    for i, page in enumerate(doc.get_pages()):
        outfp.write("START PAGE %d\n" % i)
        if page is not None:
            interpreter.process_page(page)
        outfp.write("END PAGE %d\n" % i)

    device.close()
    fp.close()

    return outfp.getvalue()

EDIT (một lần nữa):

Đã cập nhật cho phiên bản 20110515(nhờ Oeufcoque Penteano!):

def pdf_to_csv(filename):
    from cStringIO import StringIO  
    from pdfminer.converter import LTChar, TextConverter
    from pdfminer.layout import LAParams
    from pdfminer.pdfparser import PDFDocument, PDFParser
    from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter

    class CsvConverter(TextConverter):
        def __init__(self, *args, **kwargs):
            TextConverter.__init__(self, *args, **kwargs)

        def end_page(self, i):
            from collections import defaultdict
            lines = defaultdict(lambda : {})
            for child in self.cur_item._objs:                #<-- changed
                if isinstance(child, LTChar):
                    (_,_,x,y) = child.bbox                   
                    line = lines[int(-y)]
                    line[x] = child._text.encode(self.codec) #<-- changed

            for y in sorted(lines.keys()):
                line = lines[y]
                self.outfp.write(";".join(line[x] for x in sorted(line.keys())))
                self.outfp.write("\n")

    # ... the following part of the code is a remix of the 
    # convert() function in the pdfminer/tools/pdf2text module
    rsrc = PDFResourceManager()
    outfp = StringIO()
    device = CsvConverter(rsrc, outfp, codec="utf-8", laparams=LAParams())
        # becuase my test documents are utf-8 (note: utf-8 is the default codec)

    doc = PDFDocument()
    fp = open(filename, 'rb')
    parser = PDFParser(fp)       
    parser.set_document(doc)     
    doc.set_parser(parser)       
    doc.initialize('')

    interpreter = PDFPageInterpreter(rsrc, device)

    for i, page in enumerate(doc.get_pages()):
        outfp.write("START PAGE %d\n" % i)
        if page is not None:
            interpreter.process_page(page)
        outfp.write("END PAGE %d\n" % i)

    device.close()
    fp.close()

    return outfp.getvalue()

1
Trong [6]: nhập pdfminer Trong [7]: pdfminer .__ version__ Out [7]: '20100424' Trong [8]: từ pdfminer.converter nhập LTTextItem NhậpError: không thể nhập tên LTTextItem .... LITITHS_DCT_DEC LTContainer LTLine LTRect LTTextgroup LITITH_DEVICE_RGB LTF hình LTPage LTText LTTextLine
Skylar Saveland

@skyl, mã ở trên là dành cho phiên bản trước '20100213'. Từ danh sách các thay đổi nào trên trang web của họ, có vẻ như họ đã thay đổi LTTextItemđến LTChar. unixuser.org/~euske/python/pdfminer/index.html#changes
tgray

2
@Oeufcoque Penteano, cảm ơn! Tôi đã thêm một phần khác vào câu trả lời cho phiên bản 20110515cho mỗi bình luận của bạn.
tgray

1
Câu trả lời được đưa ra bởi @ user3272884 hoạt động kể từ ngày 5-1-2014
jmunsch

1
Tôi đã phải giải quyết vấn đề tương tự ngày hôm nay, sửa đổi mã của tgray một chút để trích xuất thông tin về khoảng trắng, đăng nó ở đây
tarikki

67

Vì không có giải pháp nào hỗ trợ phiên bản PDFMiner mới nhất, tôi đã viết một giải pháp đơn giản sẽ trả về văn bản của pdf bằng PDFMiner. Điều này sẽ làm việc cho những người đang nhận được lỗi nhập khẩu vớiprocess_pdf

import sys
from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter
from pdfminer.pdfpage import PDFPage
from pdfminer.converter import XMLConverter, HTMLConverter, TextConverter
from pdfminer.layout import LAParams
from cStringIO import StringIO

def pdfparser(data):

    fp = file(data, 'rb')
    rsrcmgr = PDFResourceManager()
    retstr = StringIO()
    codec = 'utf-8'
    laparams = LAParams()
    device = TextConverter(rsrcmgr, retstr, codec=codec, laparams=laparams)
    # Create a PDF interpreter object.
    interpreter = PDFPageInterpreter(rsrcmgr, device)
    # Process each page contained in the document.

    for page in PDFPage.get_pages(fp):
        interpreter.process_page(page)
        data =  retstr.getvalue()

    print data

if __name__ == '__main__':
    pdfparser(sys.argv[1])  

Xem mã dưới đây hoạt động cho Python 3:

import sys
from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter
from pdfminer.pdfpage import PDFPage
from pdfminer.converter import XMLConverter, HTMLConverter, TextConverter
from pdfminer.layout import LAParams
import io

def pdfparser(data):

    fp = open(data, 'rb')
    rsrcmgr = PDFResourceManager()
    retstr = io.StringIO()
    codec = 'utf-8'
    laparams = LAParams()
    device = TextConverter(rsrcmgr, retstr, codec=codec, laparams=laparams)
    # Create a PDF interpreter object.
    interpreter = PDFPageInterpreter(rsrcmgr, device)
    # Process each page contained in the document.

    for page in PDFPage.get_pages(fp):
        interpreter.process_page(page)
        data =  retstr.getvalue()

    print(data)

if __name__ == '__main__':
    pdfparser(sys.argv[1])  

2
đây là đoạn trích đầu tiên tôi thấy thực sự hoạt động với các tệp PDF kỳ lạ (đặc biệt là các sách điện tử miễn phí có thể nhận được từ packtpub). Mọi đoạn mã khác chỉ trả về những thứ thô được mã hóa kỳ lạ nhưng thực tế của bạn trả về văn bản. Cảm ơn!
somada141

Bạn có thể muốn thực hiện retstr.seek (0) sau khi nhận dữ liệu hoặc bạn sẽ tích lũy văn bản từ tất cả các trang.
Áo thun

2
Để sử dụng với python3, bên cạnh các dấu ngoặc đơn rõ ràng sau printlệnh, người ta phải thay thế filelệnh bằng openvà nhập StringIOtừ góiio
McLawrence

1
Ồ Khối này hoạt động hoàn hảo ngay lần đầu tiên khi tôi sao chép nó. Thật tuyệt vời! Để phân tích cú pháp và sửa chữa dữ liệu và không phải nhấn mạnh vào việc nhập dữ liệu.
SecsAndCyber

1
pdfminer không hoạt động cho python3. mã này không hoạt động cho pdfminer3k
thang

47

Pdftotext Một chương trình mã nguồn mở (một phần của Xpdf) mà bạn có thể gọi từ python (không phải những gì bạn yêu cầu nhưng có thể hữu ích). Tôi đã sử dụng nó mà không có vấn đề. Tôi nghĩ rằng google sử dụng nó trong máy tính để bàn google.


6
Đây có vẻ là công cụ hữu ích nhất trong số các công cụ được liệt kê ở đây, với -layouttùy chọn giữ văn bản ở cùng vị trí như trong PDF. Bây giờ nếu tôi chỉ có thể tìm ra cách đưa nội dung của tệp PDF vào đó.
Matthew Schinckel

Sau khi thử nghiệm một số giải pháp, đây là một lựa chọn đơn giản và mạnh mẽ nhất. Có thể dễ dàng được bao bọc bởi Python bằng cách sử dụng tempfile để ra lệnh nơi đầu ra được ghi vào.
Cerin

Cerin , sử dụng '-' làm tên tệp để chuyển hướng đầu ra sang thiết bị xuất chuẩn. Bằng cách này, bạn có thể sử dụng sub process.checkDefput đơn giản và cuộc gọi này sẽ giống như một hàm bên trong.
Ctrl-C

Chỉ để thực thi lại bất cứ ai đang sử dụng nó. . . pdftotextcó vẻ hoạt động rất tốt, nhưng nó cần một đối số thứ hai là dấu gạch nối, nếu bạn muốn xem kết quả trên thiết bị xuất chuẩn.
Gordon Linoff

1
Điều này sẽ chuyển đổi đệ quy tất cả các tệp PDF bắt đầu từ thư mục hiện tại: find . -iname "*.pdf" -exec pdftotext -enc UTF-8 -eol unix -raw {} \;Theo mặc định, các tệp được tạo có tên gốc với .txtphần mở rộng.
ccpizza

43

pyPDF hoạt động tốt (giả sử rằng bạn đang làm việc với các tệp PDF được định dạng tốt). Nếu tất cả những gì bạn muốn là văn bản (có dấu cách), bạn có thể thực hiện:

import pyPdf
pdf = pyPdf.PdfFileReader(open(filename, "rb"))
for page in pdf.pages:
    print page.extractText()

Bạn cũng có thể dễ dàng truy cập vào siêu dữ liệu, dữ liệu hình ảnh, v.v.

Một nhận xét trong ghi chú mã trích xuất:

Xác định vị trí tất cả các lệnh vẽ văn bản, theo thứ tự chúng được cung cấp trong luồng nội dung và trích xuất văn bản. Điều này hoạt động tốt đối với một số tệp PDF, nhưng kém đối với các tệp khác, tùy thuộc vào trình tạo được sử dụng. Điều này sẽ được tinh chế trong tương lai. Không dựa vào thứ tự văn bản ra khỏi chức năng này, vì nó sẽ thay đổi nếu chức năng này được thực hiện tinh vi hơn.

Đây có phải là vấn đề hay không phụ thuộc vào những gì bạn đang làm với văn bản (ví dụ: nếu đơn hàng không thành vấn đề, nó ổn hoặc nếu trình tạo thêm văn bản vào luồng theo thứ tự nó sẽ được hiển thị, thì tốt thôi) . Tôi có mã trích xuất pyPdf trong sử dụng hàng ngày, không có vấn đề gì.


7
không hỗ trợ unicode :(
PanosJee

7
pyPdf hiện hỗ trợ UTF.
lbolla

2
Thư viện này trông giống như rác. Thử nghiệm trên một tệp PDF ngẫu nhiên cho tôi biết lỗi "pyPdf.utils.PdfReadError: Không tìm thấy điểm đánh dấu EOF"
Cerin

4
Từ câu hỏi: văn bản được tạo ra không có khoảng cách giữa và không được sử dụng . Tôi đã sử dụng pyPDF và nhận được kết quả tương tự - văn bản được trích xuất không có khoảng cách giữa các từ.
Jordan Reiter

Khi tôi thực thi hàm page.extractText (), tôi gặp lỗi 'TypeError: Không thể chuyển đổi đối tượng' byte 'thành str' Làm thế nào tôi có thể xử lý vấn đề đó?
juankysmith

21

Bạn cũng có thể dễ dàng sử dụng pdfminer làm thư viện. Bạn có quyền truy cập vào mô hình nội dung của pdf và có thể tạo trích xuất văn bản của riêng bạn. Tôi đã làm điều này để chuyển đổi nội dung pdf thành văn bản tách dấu hai chấm, sử dụng mã dưới đây.

Hàm chỉ đơn giản sắp xếp các đối tượng nội dung TextItem theo tọa độ y và x của chúng và xuất ra các mục có cùng tọa độ y với một dòng văn bản, tách các đối tượng trên cùng một dòng với ';' nhân vật.

Sử dụng phương pháp này, tôi có thể trích xuất văn bản từ pdf mà không có công cụ nào khác có thể trích xuất nội dung phù hợp để phân tích cú pháp thêm. Các công cụ khác tôi đã thử bao gồm pdftotext, ps2ascii và công cụ trực tuyến pdftextonline.com.

pdfminer là một công cụ vô giá để quét pdf.


def pdf_to_csv(filename):
    from pdflib.page import TextItem, TextConverter
    from pdflib.pdfparser import PDFDocument, PDFParser
    from pdflib.pdfinterp import PDFResourceManager, PDFPageInterpreter

    class CsvConverter(TextConverter):
        def __init__(self, *args, **kwargs):
            TextConverter.__init__(self, *args, **kwargs)

        def end_page(self, i):
            from collections import defaultdict
            lines = defaultdict(lambda : {})
            for child in self.cur_item.objs:
                if isinstance(child, TextItem):
                    (_,_,x,y) = child.bbox
                    line = lines[int(-y)]
                    line[x] = child.text

            for y in sorted(lines.keys()):
                line = lines[y]
                self.outfp.write(";".join(line[x] for x in sorted(line.keys())))
                self.outfp.write("\n")

    # ... the following part of the code is a remix of the 
    # convert() function in the pdfminer/tools/pdf2text module
    rsrc = PDFResourceManager()
    outfp = StringIO()
    device = CsvConverter(rsrc, outfp, "ascii")

    doc = PDFDocument()
    fp = open(filename, 'rb')
    parser = PDFParser(doc, fp)
    doc.initialize('')

    interpreter = PDFPageInterpreter(rsrc, device)

    for i, page in enumerate(doc.get_pages()):
        outfp.write("START PAGE %d\n" % i)
        interpreter.process_page(page)
        outfp.write("END PAGE %d\n" % i)

    device.close()
    fp.close()

    return outfp.getvalue()

CẬP NHẬT :

Mã ở trên được viết dựa trên phiên bản cũ của API, xem nhận xét của tôi bên dưới.


Bạn cần loại plugin nào để làm việc đó? Tôi đã tải xuống và cài đặt pdfminer nhưng nó không đủ ...
kxk

1
Mã ở trên được viết dựa trên phiên bản cũ của PDFminer. API đã thay đổi trong các phiên bản gần đây hơn (ví dụ: gói hiện tại pdfminer, không phải pdflib). Tôi đề nghị bạn nên xem nguồn pdf2txt.pytrong nguồn PDFminer, đoạn mã trên được lấy cảm hứng từ phiên bản cũ của tệp đó.
codeape

17

slate là một dự án giúp sử dụng PDFMiner từ thư viện rất đơn giản:

>>> with open('example.pdf') as f:
...    doc = slate.PDF(f)
...
>>> doc
[..., ..., ...]
>>> doc[1]
'Text from page 2...'   

1
Tôi đang gặp lỗi nhập trong khi thực hiện "nhập slate": {Tệp "C: \ Python33 \ lib \ site-gói \ slate-0.3-py3.3.egg \ slate_ init_ .py", dòng 48, trong <module> ImportError: không thể nhập tên PDF} Nhưng lớp PDF ở đó! Bạn có biết làm thế nào để giải quyết điều này?
juankysmith

Không, điều này nghe có vẻ rất lạ. Bạn có phụ thuộc?
Tim McNamara

Thông thường tôi nhận được thông báo về các phụ thuộc bị bỏ lỡ, trong trường hợp này tôi nhận được thông báo cổ điển "Nhập tệp slate" C: \ Python33 \ lib \ site-gói \ slate-0.3-py3.3.egg \ slate_ init_ .py ", dòng 48 , trong <module> ImportError: không thể nhập tên PDF "
juankysmith

Slate 0.3 yêu cầu pdfminer 20110515, theo vấn đề GitHub này
jabbett

6
Gói này không còn được duy trì. Không sử dụng nó. Bạn thậm chí không thể sử dụng nó trong Python 3.5
Sivasubramaniam Arunachalam

9

Tôi cần chuyển đổi một tệp PDF cụ thể thành văn bản thuần túy trong mô-đun python. Tôi đã sử dụng PDFMiner 20110515, sau khi đọc qua công cụ pdf2txt.py của họ, tôi đã viết đoạn trích đơn giản này:

from cStringIO import StringIO
from pdfminer.pdfinterp import PDFResourceManager, process_pdf
from pdfminer.converter import TextConverter
from pdfminer.layout import LAParams

def to_txt(pdf_path):
    input_ = file(pdf_path, 'rb')
    output = StringIO()

    manager = PDFResourceManager()
    converter = TextConverter(manager, output, laparams=LAParams())
    process_pdf(manager, converter, input_)

    return output.getvalue() 

1
def to_txt (pdf_path):
Cătălin George Feștilă

Nếu tôi chỉ muốn chuyển đổi một số trang nhất định, tôi sẽ làm thế nào với mã này?
psychok7

@ psychok7 Bạn đã thử sử dụng công cụ pdf2txt chưa? Dường như hỗ trợ tính năng đó trong phiên bản hiện tại với cờ -p, việc triển khai có vẻ dễ thực hiện và cũng dễ tùy chỉnh: github.com/euske/pdfminer/blob/master/tools/pdf2txt.py Hy vọng nó sẽ giúp! :)
gonz

1
thanx @gonz, tôi đã thử tất cả các cách trên nhưng giải pháp của bạn hóa ra là hoàn hảo đối với tôi ,, đầu ra có khoảng trắng :)
lazarus

pdf2txt.py được cài đặt tại đây cho tôi:C:\Python27\Scripts\pdfminer\tools\pdf2txt.py
The Red Pea

6

Tái sử dụng mã pdf2txt.py đi kèm với pdfminer; bạn có thể tạo một hàm sẽ đưa một đường dẫn đến pdf; tùy chọn, một loại outtype (txt | html | xml | tag) và hoạt động như dòng lệnh pdf2txt {'-o': '/path/to/outfile.txt' ...}. Theo mặc định, bạn có thể gọi:

convert_pdf(path)

Một tệp văn bản sẽ được tạo, anh chị em trên hệ thống tệp với pdf gốc.

def convert_pdf(path, outtype='txt', opts={}):
    import sys
    from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter, process_pdf
    from pdfminer.converter import XMLConverter, HTMLConverter, TextConverter, TagExtractor
    from pdfminer.layout import LAParams
    from pdfminer.pdfparser import PDFDocument, PDFParser
    from pdfminer.pdfdevice import PDFDevice
    from pdfminer.cmapdb import CMapDB

    outfile = path[:-3] + outtype
    outdir = '/'.join(path.split('/')[:-1])

    debug = 0
    # input option
    password = ''
    pagenos = set()
    maxpages = 0
    # output option
    codec = 'utf-8'
    pageno = 1
    scale = 1
    showpageno = True
    laparams = LAParams()
    for (k, v) in opts:
        if k == '-d': debug += 1
        elif k == '-p': pagenos.update( int(x)-1 for x in v.split(',') )
        elif k == '-m': maxpages = int(v)
        elif k == '-P': password = v
        elif k == '-o': outfile = v
        elif k == '-n': laparams = None
        elif k == '-A': laparams.all_texts = True
        elif k == '-D': laparams.writing_mode = v
        elif k == '-M': laparams.char_margin = float(v)
        elif k == '-L': laparams.line_margin = float(v)
        elif k == '-W': laparams.word_margin = float(v)
        elif k == '-O': outdir = v
        elif k == '-t': outtype = v
        elif k == '-c': codec = v
        elif k == '-s': scale = float(v)
    #
    CMapDB.debug = debug
    PDFResourceManager.debug = debug
    PDFDocument.debug = debug
    PDFParser.debug = debug
    PDFPageInterpreter.debug = debug
    PDFDevice.debug = debug
    #
    rsrcmgr = PDFResourceManager()
    if not outtype:
        outtype = 'txt'
        if outfile:
            if outfile.endswith('.htm') or outfile.endswith('.html'):
                outtype = 'html'
            elif outfile.endswith('.xml'):
                outtype = 'xml'
            elif outfile.endswith('.tag'):
                outtype = 'tag'
    if outfile:
        outfp = file(outfile, 'w')
    else:
        outfp = sys.stdout
    if outtype == 'txt':
        device = TextConverter(rsrcmgr, outfp, codec=codec, laparams=laparams)
    elif outtype == 'xml':
        device = XMLConverter(rsrcmgr, outfp, codec=codec, laparams=laparams, outdir=outdir)
    elif outtype == 'html':
        device = HTMLConverter(rsrcmgr, outfp, codec=codec, scale=scale, laparams=laparams, outdir=outdir)
    elif outtype == 'tag':
        device = TagExtractor(rsrcmgr, outfp, codec=codec)
    else:
        return usage()

    fp = file(path, 'rb')
    process_pdf(rsrcmgr, device, fp, pagenos, maxpages=maxpages, password=password)
    fp.close()
    device.close()

    outfp.close()
    return

1

PDFminer đã cho tôi có lẽ một dòng [trang 1 trên 7 ...] trên mỗi trang của tệp pdf tôi đã thử với nó.

Câu trả lời tốt nhất tôi có cho đến nay là pdftoipe, hoặc mã c ++ dựa trên Xpdf.

xem câu hỏi của tôi để biết đầu ra của pdftoipe trông như thế nào.



1

Tôi đã sử dụng pdftohtmlvới -xmlđối số, đọc kết quả với subprocess.Popen(), nó sẽ cung cấp cho bạn tọa độ x, tọa độ y, chiều rộng, chiều cao và phông chữ của mỗi đoạn văn bản trong pdf. Tôi nghĩ rằng đây là những gì 'evince' có thể sử dụng vì các thông báo lỗi tương tự xuất hiện.

Nếu bạn cần xử lý dữ liệu cột, nó sẽ phức tạp hơn một chút vì bạn phải phát minh ra một thuật toán phù hợp với tệp pdf của mình. Vấn đề là các chương trình tạo tệp PDF không thực sự bố trí văn bản theo bất kỳ định dạng logic nào. Bạn có thể thử các thuật toán sắp xếp đơn giản và đôi khi nó hoạt động, nhưng có thể có một ít 'stragglers' và 'strays', các đoạn văn bản không được đặt theo thứ tự bạn nghĩ chúng sẽ làm. Vì vậy, bạn phải có được sáng tạo.

Tôi mất khoảng 5 giờ để tìm ra một bản pdf mà tôi đang làm việc. Nhưng nó hoạt động khá tốt bây giờ. Chúc may mắn.


Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.