μονάδα Python για τη μετατροπή PDF σε κείμενο

ψήφοι
341

Ποιες είναι οι καλύτερες μονάδες Python για να μετατρέψετε αρχεία PDF σε κείμενο;

Δημοσιεύθηκε 25/08/2008 στις 03:44
πηγή χρήστη
Σε άλλες γλώσσες...                            


13 απαντήσεις

ψήφοι
116

Δοκιμάστε PDFMiner. Μπορεί να εξαχθεί το κείμενο από αρχεία PDF σε μορφή HTML, SGML ή «Κολλημένος PDF» μορφή.

http://www.unixuser.org/~euske/python/pdfminer/index.html

Η Tagged μορφή PDF φαίνεται να είναι η πιο καθαρή, και αφαιρεί τις ετικέτες XML αφήνει μόνο το γυμνό κείμενο.

Η Python 3 έκδοση είναι διαθέσιμη κάτω:

Απαντήθηκε 25/08/2008 στις 04:21
πηγή χρήστη

ψήφοι
0

PDFminer μου έδωσε ίσως μία γραμμή [Σελίδα 1 από 7 ...] σε κάθε σελίδα ενός αρχείου pdf Προσπάθησα με αυτό.

Η καλύτερη απάντηση που έχω μέχρι στιγμής είναι pdftoipe, ή το γ κωδικός ++ είναι βασισμένο σε Xpdf.

δείτε ερώτησή μου για το ποια είναι η έξοδος της pdftoipe μοιάζει.

Απαντήθηκε 26/08/2008 στις 01:04
πηγή χρήστη

ψήφοι
39

Pdftotext ένα πρόγραμμα ανοιχτού κώδικα (μέρος Xpdf), το οποίο μπορείτε να καλέσετε από πύθωνα (δεν είναι αυτό που ζήτησε, αλλά μπορεί να είναι χρήσιμο). Το έχω χρησιμοποιήσει χωρίς προβλήματα. Νομίζω ότι το google το χρησιμοποιήσετε στο desktop google.

Απαντήθηκε 28/08/2008 στις 08:46
πηγή χρήστη

ψήφοι
42

pyPDF δουλεύει μια χαρά (αν υποτεθεί ότι εργάζεστε με καλοσχηματισμένα αρχεία PDF). Αν το μόνο που θέλετε είναι το κείμενο (με κενά), μπορείτε απλά να κάνετε:

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

Μπορείτε επίσης να πάρετε εύκολα πρόσβαση στα μεταδεδομένα, δεδομένα εικόνας, και ούτω καθεξής.

Ένα σχόλιο στον κώδικα extractText σημειώσεις:

Εντοπίστε όλες τις εντολές σχεδίασης κείμενο, με τη σειρά που παρέχονται στο ρεύμα περιεχόμενο, και εκχυλίστε το κείμενο. Αυτό λειτουργεί καλά για κάποια αρχεία PDF, αλλά κακώς για τους άλλους, ανάλογα με την γεννήτρια που χρησιμοποιείται. Αυτό θα πρέπει να βελτιωθεί στο μέλλον. Μην βασίζεστε της τάξης του κειμένου που βγαίνει από αυτή τη λειτουργία, καθώς θα αλλάξει εάν αυτή η λειτουργία γίνεται πιο περίπλοκο.

Το αν αυτό δεν είναι ένα πρόβλημα που εξαρτάται από το τι κάνετε με το κείμενο (π.χ. αν η σειρά δεν έχει σημασία, είναι ωραία, ή αν η γεννήτρια προσθέτει κείμενο στο ρεύμα με τη σειρά που θα εμφανιστούν, είναι μια χαρά) . Έχω κωδικό εξόρυξη pyPdf στην καθημερινή χρήση, χωρίς προβλήματα.

Απαντήθηκε 07/09/2008 στις 03:47
πηγή χρήστη

ψήφοι
1

Επιπλέον υπάρχει PDFTextStream το οποίο είναι ένα εμπορικό βιβλιοθήκη Java που μπορεί να χρησιμοποιηθεί και από την Python.

Απαντήθηκε 12/11/2008 στις 16:08
πηγή χρήστη

ψήφοι
21

Μπορείτε επίσης πολύ εύκολα να χρησιμοποιήσετε pdfminer ως βιβλιοθήκη. Έχετε πρόσβαση στο πρότυπο περιεχόμενο του PDF, και να δημιουργήσετε το δικό εξόρυξη κειμένου σας. Το έκανα αυτό για να μετατρέψετε το περιεχόμενο pdf στο ερωτηματικό διαχωρίζονται κείμενο, χρησιμοποιώντας τον παρακάτω κώδικα.

Η λειτουργία ταξινομεί απλώς τα αντικείμενα περιεχομένου TextItem ανάλογα με y τους και το χ συντεταγμένες, και εξάγει αντικείμενα με το ίδιο y συντεταγμένη ως μία γραμμή κειμένου, διαχωρίζοντας τα αντικείμενα στην ίδια γραμμή με «?» χαρακτήρες.

Χρησιμοποιώντας αυτή την προσέγγιση, ήμουν σε θέση να εξαγάγετε κείμενο από ένα pdf που κανένα άλλο εργαλείο που ήταν σε θέση να εξάγει το περιεχόμενο κατάλληλο για περαιτέρω ανάλυσης από. Άλλα εργαλεία Προσπάθησα περιλαμβάνουν pdftotext, ps2ascii και την online pdftextonline.com εργαλείο.

pdfminer είναι ένα ανεκτίμητο εργαλείο για 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()

UPDATE :

Η παραπάνω κώδικα είναι γραμμένο κατά μια παλιά έκδοση του API, δείτε το σχόλιό μου παρακάτω.

Απαντήθηκε 24/11/2008 στις 13:20
πηγή χρήστη

ψήφοι
130

Η PDFMiner πακέτο έχει αλλάξει από codeape δημοσιεύτηκε.

EDIT (και πάλι):

PDFMiner έχει ενημερωθεί και πάλι στην έκδοση 20100213

Μπορείτε να ελέγξετε την έκδοση που έχετε εγκαταστήσει από το ακόλουθο κείμενο:

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

Εδώ είναι η ενημερωμένη έκδοση (με σχόλια σχετικά με το τι θα αλλάξει / προστεθεί):

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

Επεξεργασία (και πάλι):

Εδώ είναι μια ενημερωμένη έκδοση για την τελευταία έκδοση στο pypi , 20100619p1. Εν ολίγοις Ι αντικαθίσταται LTTextItemμε LTCharκαι πέρασε μια παρουσία LAParams στον κατασκευαστή 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 (άλλη μια φορά):

Ενημέρωση για την έκδοση 20110515(χάρη στην 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()
Απαντήθηκε 10/08/2009 στις 19:47
πηγή χρήστη

ψήφοι
5

Αναπροσανατολισμό τον κωδικό pdf2txt.py που έρχεται με pdfminer? μπορείτε να κάνετε μια λειτουργία που θα λάβει μια διαδρομή προς το pdf? προαιρετικά, ένα outtype (txt | html | XML | tag) και επιλέγει σαν την γραμμή εντολών Pdf2Txt { '-ο': '/path/to/outfile.txt' ...}. Από προεπιλογή, μπορείτε να καλέσετε:

convert_pdf(path)

Θα δημιουργηθεί ένα αρχείο κειμένου, ένα αδελφό στο σύστημα αρχείων στην αρχική pdf.

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
Απαντήθηκε 18/07/2010 στις 18:17
πηγή χρήστη

ψήφοι
1

Έχω χρησιμοποιήσει pdftohtml με το «-xml επιχείρημα, διαβάστε το αποτέλεσμα με subprocess.Popen (), που θα σας δώσει χ coord, y coord, πλάτος, ύψος, και τη γραμματοσειρά, κάθε«απόσπασμα»του κειμένου στο pdf. Νομίζω ότι αυτό είναι ό, τι «evince» πιθανώς χρησιμοποιεί πάρα πολύ, διότι τα ίδια μηνύματα λάθους διασπείρουν.

Αν χρειαστεί να επεξεργάζεται στήλες δεδομένων, γίνεται λίγο πιο περίπλοκη καθώς θα πρέπει να εφεύρουμε έναν αλγόριθμο που ταιριάζει αρχείο pdf σας. Το πρόβλημα είναι ότι τα προγράμματα που κάνουν τα αρχεία PDF δεν είναι πραγματικά απαραίτητα απλώστε το κείμενο σε οποιαδήποτε λογική μορφή. Μπορείτε να δοκιμάσετε απλή αλγορίθμους ταξινόμησης και λειτουργεί μερικές φορές, αλλά δεν μπορεί να υπάρξει μικρή «παράξενες» και «αδέσποτα», κομμάτια του κειμένου που δεν παίρνουν θέσει με τη σειρά που νόμιζαν ότι θα ήταν ... έτσι πρέπει να πάρετε δημιουργικοί.

Μου πήρε περίπου 5 ώρες για να καταλάβω ένα για τα pdf του δούλευα. Αλλά αυτό λειτουργεί αρκετά καλά τώρα. Καλή τύχη.

Απαντήθηκε 12/11/2010 στις 21:34
πηγή χρήστη

ψήφοι
0

Βρέθηκε ότι η λύση σήμερα. Λειτουργεί μεγάλο για μένα. Ακόμη και καθιστώντας σελίδες PDF σε εικόνες PNG. http://www.swftools.org/gfx_tutorial.html

Απαντήθηκε 30/01/2011 στις 23:22
πηγή χρήστη

ψήφοι
16

slate Είναι ένα έργο που το καθιστά πολύ απλό στη χρήση PDFMiner από μια βιβλιοθήκη:

>>> with open('example.pdf') as f:
...    doc = slate.PDF(f)
...
>>> doc
[..., ..., ...]
>>> doc[1]
'Text from page 2...'   
Απαντήθηκε 30/01/2011 στις 23:27
πηγή χρήστη

ψήφοι
8

Έπρεπε να μετατρέψετε ένα συγκεκριμένο PDF σε μορφή απλού κειμένου μέσα σε μια μονάδα python. Θα χρησιμοποιηθεί PDFMiner 20110515, μετά την ανάγνωση μέσα από τους pdf2txt.py εργαλείο που έγραψα αυτό το απλό απόσπασμα:

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() 
Απαντήθηκε 28/05/2013 στις 15:01
πηγή χρήστη

ψήφοι
49

Δεδομένου ότι κανένας για τις λύσεις αυτές υποστηρίζουν την τελευταία έκδοση του PDFMiner έγραψα μια απλή λύση που θα επιστρέψει κείμενο pdf χρησιμοποιώντας PDFMiner. Αυτό θα λειτουργήσει για εκείνους που παίρνουν τα λάθη εισαγωγής μεprocess_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])  

Δείτε παρακάτω κώδικα που λειτουργεί για 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])  
Απαντήθηκε 04/02/2014 στις 20:16
πηγή χρήστη

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more