Modulo Python per convertire PDF in testo [chiuso]


385

Esiste un modulo Python per convertire i file PDF in testo? Ho provato un pezzo di codice trovato in Activestate che utilizza pypdf ma il testo generato non aveva spazio tra di loro e non era di alcuna utilità.


1
Stavo cercando una soluzione simile. Devo solo leggere il testo dal file pdf. Non ho bisogno delle immagini. pdfminer è una buona scelta ma non ho trovato un semplice esempio su come estrarre il testo. Alla fine ho ottenuto questa risposta SO ( stackoverflow.com/questions/5725278/… ) e ora la utilizzo.
Nayan,

2
Da quando la domanda è stata chiusa, l'ho ripubblicata nello Stack Exchange dedicato ai consigli sul software nel caso in cui qualcuno volesse scrivere una nuova risposta: modulo Python per convertire i PDF in testo
Franck Dernoncourt

1
L'unica soluzione che ha funzionato per me per i contenuti UTF-8: Apache Tika
Shoham

Vorrei aggiornare l'elenco delle opzioni disponibili per la conversione da PDF a testo in Python, GroupDocs.Conversion Cloud SDK per Python converte il PDF in testo con precisione.
Tilal Ahmad,

Risposte:


142

Prova PDFMiner . Può estrarre testo da file PDF in formato HTML, SGML o "Tagged PDF".

Il formato PDF con tag sembra essere il più pulito e l'eliminazione dei tag XML lascia solo il testo nudo.

Una versione di Python 3 è disponibile sotto:


2
Ho appena aggiunto una risposta descrivendo come utilizzare pdfminer come libreria.
codeape,

24
nessun supporto per Python 3 :(
Karl Adler,

1
La risposta che ho fornito in questo thread potrebbe essere utile per le persone che guardano questa risposta e si chiedono come utilizzare la libreria. Fornisco un esempio su come utilizzare la libreria PDFMiner per estrarre il testo dal PDF. Dal momento che la documentazione è un po 'scarsa, ho pensato che potesse aiutare alcune persone.
DuckPuncher,

17
per quanto riguarda python 3, esiste un fork a sei basi pypi.python.org/pypi/pdfminer.six
Denis Cornehl,


136

Il pacchetto PDFMiner è cambiato da quando è stato pubblicato codeape .

MODIFICA (di nuovo):

PDFMiner è stato nuovamente aggiornato nella versione 20100213

È possibile verificare la versione installata con quanto segue:

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

Ecco la versione aggiornata (con commenti su ciò che ho modificato / aggiunto):

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

Modifica (ancora una volta):

Ecco un aggiornamento per la versione più recente di PyPI , 20100619p1. In breve sostituito LTTextItemcon LTChare passai un'istanza LAParams al costruttore 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()

MODIFICA (ancora una volta):

Aggiornato per la versione 20110515(grazie a 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
In [6]: import pdfminer In [7]: pdfminer .__ versione__ Out [7]: '20100424' In [8]: da pdfminer.converter import LTTextItem ImportError: impossibile importare il nome LTTextItem .... LITERALS_DCT_DECODE LTChar LTImage LTPolygon LTTextBox LITER_IT LTContainer LTLine LTRect LTTextGroup LITERAL_DEVICE_RGB LTFigura LTPage LTText LTTextLine
Skylar Saveland

@skyl, il codice sopra è per la versione precedente '20100213'. Dall'elenco delle modifiche sul loro sito Web, sembra che siano cambiate LTTextItemin LTChar. unixuser.org/~euske/python/pdfminer/index.html#changes
tgray

2
@Oeufcoque Penteano, grazie! Ho aggiunto un'altra sezione alla risposta per la versione 20110515per il tuo commento.
Tgray

1
La risposta data da @ user3272884 funziona dal 5-1-2014
jmunsch

1
Oggi ho dovuto risolvere lo stesso problema, modificato un po 'il codice di tgray per estrarre informazioni sugli spazi bianchi, pubblicato qui
tarikki,

67

Poiché nessuna di queste soluzioni supporta l'ultima versione di PDFMiner, ho scritto una soluzione semplice che restituirà il testo di un pdf utilizzando PDFMiner. Questo funzionerà per coloro che ottengono errori di importazione conprocess_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])  

Vedi sotto il codice che funziona per 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
questo è il primo frammento che ho trovato che funziona con strani file PDF (in particolare gli ebook gratuiti che si possono ottenere da packtpub). Ogni altro pezzo di codice restituisce semplicemente le cose grezze codificate in modo strano ma il tuo in realtà restituisce testo. Grazie!
somada141

Probabilmente vuoi fare retstr.seek (0) dopo aver ottenuto i dati, o accumulerai testo da tutte le pagine.
Tshirtman

2
Per usare python3, oltre alle ovvie parentesi dopo il printcomando, si deve sostituire il filecomando con opene importarlo StringIOdal pacchettoio
McLawrence,

1
Wow. Questo blocco ha funzionato perfettamente la prima volta che l'ho copiato. Incredibile! Analizzare e correggere i dati e non doversi preoccupare di immetterli.
SecsAndCyber,

1
pdfminer non funziona per python3. questo codice non funziona per pdfminer3k
thang

47

Pdftotext Un programma open source (parte di Xpdf) che potresti chiamare da Python (non quello che hai chiesto ma potrebbe essere utile). L'ho usato senza problemi. Penso che Google lo usi nel desktop di Google.


6
Questo sembra essere il più utile degli strumenti elencati qui, con l' -layoutopzione di mantenere il testo nella stessa posizione del PDF. Ora, se solo potessi capire come convogliare il contenuto di un PDF in esso.
Matthew Schinckel,

Dopo aver testato diverse soluzioni, questa sembra l'opzione più semplice e robusta. Può essere facilmente spostato da Python usando un tempfile per dettare dove viene scritto l'output.
Cerin,

Cerin , usa '-' come nome file per reindirizzare l'output su stdout. In questo modo puoi utilizzare subprocess.check_output semplice e questa chiamata sembrerebbe una funzione interna.
Ctrl-C,

Solo per rinforzare chiunque lo stia usando. . . pdftotextsembra funzionare molto bene, ma ha bisogno di un secondo argomento che sia un trattino, se vuoi vedere i risultati su stdout.
Gordon Linoff,

1
Ciò convertirà ricorsivamente tutti i file PDF a partire dalla cartella corrente: find . -iname "*.pdf" -exec pdftotext -enc UTF-8 -eol unix -raw {} \;per impostazione predefinita, i file generati assumono il nome originale con l' .txtestensione.
ccpizza,

43

pyPDF funziona bene (supponendo che tu stia lavorando con PDF ben formati). Se tutto ciò che vuoi è il testo (con spazi), puoi semplicemente fare:

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

Puoi anche accedere facilmente ai metadati, ai dati delle immagini e così via.

Un commento nelle note del codice extractText:

Individua tutti i comandi di disegno del testo, nell'ordine in cui sono forniti nel flusso di contenuto, ed estrai il testo. Funziona bene con alcuni file PDF, ma male per altri, a seconda del generatore utilizzato. Questo sarà perfezionato in futuro. Non fare affidamento sull'ordine del testo che esce da questa funzione, poiché cambierà se questa funzione viene resa più sofisticata.

Se questo è un problema o meno dipende da cosa stai facendo con il testo (ad es. Se l'ordine non ha importanza, va bene, o se il generatore aggiunge testo allo stream nell'ordine in cui verrà visualizzato, va bene) . Ho un codice di estrazione pyPdf nell'uso quotidiano, senza problemi.


7
nessun supporto Unicode :(
PanosJee

7
pyPdf ora supporta UTF.
lbolla,

2
Questa libreria sembra spazzatura. Test su un PDF casuale mi dà l'errore "pyPdf.utils.PdfReadError: marker EOF non trovato"
Cerin

4
Dalla domanda: il testo generato non aveva spazio tra di loro e non era di alcuna utilità . Ho usato pyPDF e ho ottenuto lo stesso risultato: il testo viene estratto senza spazi tra le parole.
Jordan Reiter,

Quando eseguo la funzione page.extractText () viene visualizzato l'errore 'TypeError: impossibile convertire l'oggetto' bytes 'in str implicitamente' Come posso gestirlo?
juankysmith l'

21

Puoi anche usare PDFminer abbastanza facilmente come libreria. Hai accesso al modello di contenuto del pdf e puoi creare la tua estrazione di testo. Ho fatto questo per convertire i contenuti pdf in testo separato da punti e virgola, usando il codice qui sotto.

La funzione ordina semplicemente gli oggetti di contenuto TextItem in base alle loro coordinate y e x e genera elementi con la stessa coordinata y di una riga di testo, separando gli oggetti sulla stessa riga con ';' personaggi.

Usando questo approccio, sono stato in grado di estrarre il testo da un pdf che nessun altro strumento è stato in grado di estrarre il contenuto adatto per ulteriori analisi. Altri strumenti che ho provato includono pdftotext, ps2ascii e lo strumento online pdftextonline.com.

pdfminer è uno strumento prezioso per la raschiatura di 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()

AGGIORNAMENTO :

Il codice sopra è scritto su una vecchia versione dell'API, vedi il mio commento qui sotto.


Che tipo di plugin hai bisogno per farlo funzionare amico? Ho scaricato e installato pdfminer ma non è abbastanza ...
kxk

1
Il codice sopra è scritto contro una vecchia versione di PDFminer. L'API è cambiato nelle versioni più recenti (per esempio, il pacchetto è ora pdfminer, non pdflib). Ti suggerisco di dare un'occhiata alla fonte di pdf2txt.pyPDFminer, il codice sopra è stato ispirato dalla vecchia versione di quel file.
codeape,

17

slate è un progetto che semplifica l'utilizzo di PDFMiner da una libreria:

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

1
Ricevo un errore di importazione durante l'esecuzione di "lista di importazione": {File "C: \ Python33 \ lib \ site-pacchetti \ slate-0.3-py3.3.egg \ slate_ init_ .py", riga 48, in <modulo> ImportError: impossibile importare il nome PDF} Ma la classe PDF è lì! Sai come risolverlo?
juankysmith,

No, sembra molto strano. Hai le dipendenze?
Tim McNamara,

Normalmente ricevo messaggi su dipendenze mancate, in questo caso ricevo il classico messaggio "importa file ardesia" C: \ Python33 \ lib \ site-pacchetti \ slate-0.3-py3.3.egg \ slate_ init_ .py ", linea 48 , in <modulo> ImportError: impossibile importare il nome PDF "
juankysmith

Slate 0.3 richiede pdfminer 20110515, secondo questo numero di GitHub
jabbett

6
Questo pacchetto non è più gestito. Evita di usarlo. Non puoi nemmeno usarlo in Python 3.5
Sivasubramaniam Arunachalam

9

Avevo bisogno di convertire un PDF specifico in testo normale all'interno di un modulo Python. Ho usato PDFMiner 20110515, dopo aver letto il loro strumento pdf2txt.py ho scritto questo semplice frammento:

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ă

se volessi convertire solo un certo numero di pagine, come farei con questo codice?
psychok7,

@ psychok7 Hai provato a usare lo strumento pdf2txt? Sembra supportare questa funzione nella versione corrente con il flag -p, l'implementazione sembra facile da seguire e dovrebbe essere facile anche da personalizzare: github.com/euske/pdfminer/blob/master/tools/pdf2txt.py Spero che sia d'aiuto! :)
gonz,

1
grazie @gonz, ho provato per tutto quanto sopra ma la tua soluzione risulta essere perfetta per me, uscita con spazi :)
lazarus

pdf2txt.py è installato qui per me:C:\Python27\Scripts\pdfminer\tools\pdf2txt.py
The Red Pea

6

Riproporre il codice pdf2txt.py fornito con pdfminer; puoi fare una funzione che prenderà un percorso per il pdf; opzionalmente, un outtype (txt | html | xml | tag) e opta come la riga di comando pdf2txt {'-o': '/path/to/outfile.txt' ...}. Per impostazione predefinita, è possibile chiamare:

convert_pdf(path)

Verrà creato un file di testo, un fratello sul filesystem nel pdf originale.

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 mi ha dato forse una riga [pagina 1 di 7 ...] su ogni pagina di un file pdf che ho provato con esso.

La migliore risposta che ho finora è pdftoipe, o il codice c ++ è basato su Xpdf.

vedi la mia domanda su come appare l'output di pdftoipe.



1

Ho usato pdftohtmll' -xmlargomento, ho letto il risultato con subprocess.Popen(), che ti darà x coord, y coord, larghezza, altezza e carattere, di ogni frammento di testo nel pdf. Penso che questo sia ciò che probabilmente "evince" usa anche perché vengono emessi gli stessi messaggi di errore.

Se hai bisogno di elaborare dati colonnari, diventa leggermente più complicato in quanto devi inventare un algoritmo adatto al tuo file pdf. Il problema è che i programmi che creano file PDF non strutturano necessariamente il testo in alcun formato logico. Puoi provare semplici algoritmi di ordinamento e a volte funziona, ma possono esserci piccoli "sbandati" e "randagi", pezzi di testo che non vengono messi nell'ordine che pensavi avrebbero fatto. Quindi devi essere creativo.

Mi ci sono volute circa 5 ore per capirne uno per il pdf a cui stavo lavorando. Ma ora funziona abbastanza bene. In bocca al lupo.


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.