Module Python pour convertir des PDF en texte [fermé]

385

Existe-t-il un module python pour convertir des fichiers PDF en texte? J'ai essayé un morceau de code trouvé dans Activestate qui utilise pypdf mais le texte généré n'avait pas d'espace entre et n'était d'aucune utilité.

cnu
la source
1
Je cherchais une solution similaire. J'ai juste besoin de lire le texte du fichier pdf. Je n'ai pas besoin des images. pdfminer est un bon choix mais je n'ai pas trouvé d'exemple simple sur la façon d'extraire le texte. Enfin, j'ai obtenu cette réponse SO ( stackoverflow.com/questions/5725278/… ) et je l'utilise maintenant.
Nayan
2
Depuis la clôture de la question, je l'ai republiée sur le Stack Exchange dédié aux recommandations logicielles au cas où quelqu'un voudrait écrire une nouvelle réponse: Module Python pour convertir des PDF en texte
Franck Dernoncourt
1
La seule solution qui a fonctionné pour moi pour le contenu UTF-8: Apache Tika
Shoham
Je voudrais mettre à jour la liste des options disponibles pour la conversion de PDF en texte en Python, GroupDocs.Conversion Cloud SDK pour Python convertit le PDF en texte avec précision.
Tilal Ahmad

Réponses:

142

Essayez PDFMiner . Il peut extraire le texte des fichiers PDF au format HTML, SGML ou "PDF balisé".

Le format PDF balisé semble être le plus propre, et supprimer les balises XML ne laisse que le texte nu.

Une version Python 3 est disponible sous:

David Crow
la source
2
Je viens d'ajouter une réponse décrivant comment utiliser pdfminer comme bibliothèque.
codeape
24
pas de support pour python 3 :(
Karl Adler
1
La réponse que j'ai fournie dans ce fil pourrait être utile pour les personnes qui regardent cette réponse et se demandent comment utiliser la bibliothèque. Je donne un exemple sur la façon d'utiliser la bibliothèque PDFMiner pour extraire du texte du PDF. Étant donné que la documentation est un peu clairsemée, je pensais que cela pourrait aider quelques personnes.
DuckPuncher
17
en ce qui concerne python 3, il y a un fork à six bases pypi.python.org/pypi/pdfminer.six
Denis Cornehl
1
exemple de code sur stackoverflow.com/a/26495057/125617
Renaud
136

Le package PDFMiner a changé depuis la publication de codeape .

MODIFIER (encore):

PDFMiner a été mis à jour à nouveau dans la version 20100213

Vous pouvez vérifier la version que vous avez installée avec les éléments suivants:

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

Voici la version mise à jour (avec des commentaires sur ce que j'ai changé / ajouté):

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

Modifier (encore une fois):

Voici une mise à jour pour la dernière version en pypi , 20100619p1. En bref , j'ai remplacé LTTextItemavec LTCharet passé une instance de LAParams au constructeur de 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()

MODIFIER (encore une fois):

Mise à jour pour la version 20110515(merci à 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()
tgray
la source
1
In [6]: import pdfminer In [7]: pdfminer .__ version__ Out [7]: '20100424' In [8]: from pdfminer.converter import LTTextItem ImportError: impossible d'importer le nom LTTextItem .... LITERALS_DCT_DECODE LTChar LTImage LTPolygon LTTextBox LITERALY LTContainer LTLine LTRect LTTextGroup LITERAL_DEVICE_RGB LTFigure LTPage LTText LTTextLine
Skylar Saveland
@skyl, le code ci-dessus est pour la version précédente '20100213'. D'après la liste des modifications sur leur site Web, il semble qu'ils soient passés LTTextItemà LTChar. unixuser.org/~euske/python/pdfminer/index.html#changes
tgray
2
@Oeufcoque Penteano, merci! J'ai ajouté une autre section à la réponse pour la version 20110515par votre commentaire.
tgray
1
La réponse donnée par @ user3272884 fonctionne à partir du 5-1-2014
jmunsch
1
J'ai dû résoudre ce même problème aujourd'hui, modifié un peu le code de tgray pour extraire des informations sur les espaces blancs, l'a publié ici
tarikki
67

Étant donné qu'aucune de ces solutions ne prend en charge la dernière version de PDFMiner, j'ai écrit une solution simple qui retournera le texte d'un pdf à l'aide de PDFMiner. Cela fonctionnera pour ceux qui obtiennent des erreurs d'importation avecprocess_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])  

Voir ci-dessous le code qui fonctionne pour 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])  
user3272884
la source
2
c'est le premier extrait que j'ai trouvé qui fonctionne réellement avec des fichiers PDF étranges (en particulier les ebooks gratuits que l'on peut obtenir de packtpub). Tous les autres morceaux de code renvoient simplement les éléments bruts étrangement encodés, mais le vôtre renvoie en fait du texte. Merci!
somada141
Vous voudrez probablement faire retstr.seek (0) après avoir obtenu les données, ou vous accumulerez du texte de toutes les pages.
Tshirtman
2
Pour utiliser avec python3, outre les parenthèses évidentes après la printcommande, il faut remplacer la filecommande par openet importer à StringIOpartir du packageio
McLawrence
1
Sensationnel. Ce bloc a parfaitement fonctionné la première fois que je l'ai copié. Incroyable! Pour analyser et corriger les données et ne pas avoir à se soucier de la saisie.
SecsAndCyber
1
pdfminer ne fonctionne pas pour python3. ce code ne fonctionne pas pour pdfminer3k
thang
47

Pdftotext Un programme open source (partie de Xpdf) que vous pourriez appeler depuis python (pas ce que vous avez demandé mais qui pourrait être utile). Je l'ai utilisé sans problème. Je pense que Google l'utilise dans Google Desktop.

Jamie
la source
6
Cela semble être le plus utile des outils répertoriés ici, avec la -layoutpossibilité de conserver le texte dans la même position que dans le PDF. Maintenant, si seulement je pouvais comprendre comment y diriger le contenu d'un PDF.
Matthew Schinckel
Après avoir testé plusieurs solutions, celle-ci semble être l'option la plus simple et la plus robuste. Peut facilement être encapsulé par Python à l'aide d'un fichier temporaire pour dicter où la sortie est écrite.
Cerin
Cerin , utilisez '-' comme nom de fichier pour rediriger la sortie vers stdout. De cette façon, vous pouvez utiliser un simple subprocess.check_output et cet appel ressemblerait à une fonction interne.
Ctrl-C
Juste pour renforcer ceux qui l'utilisent. . . pdftotextsemble fonctionner très bien, mais il a besoin d'un deuxième argument qui est un trait d'union, si vous voulez voir les résultats sur stdout.
Gordon Linoff
1
Cela convertira récursivement tous les fichiers PDF à partir du dossier actuel: find . -iname "*.pdf" -exec pdftotext -enc UTF-8 -eol unix -raw {} \;Par défaut, les fichiers générés prennent le nom d'origine avec l' .txtextension.
ccpizza
43

pyPDF fonctionne bien (en supposant que vous travaillez avec des fichiers PDF bien formés). Si tout ce que vous voulez c'est le texte (avec des espaces), vous pouvez simplement faire:

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

Vous pouvez également accéder facilement aux métadonnées, aux données d'image, etc.

Un commentaire dans les notes de code extractText:

Recherchez toutes les commandes de dessin de texte, dans l'ordre dans lequel elles sont fournies dans le flux de contenu, et extrayez le texte. Cela fonctionne bien pour certains fichiers PDF, mais mal pour d'autres, selon le générateur utilisé. Cela sera affiné à l'avenir. Ne vous fiez pas à l'ordre du texte sortant de cette fonction, car il changera si cette fonction est rendue plus sophistiquée.

Que ce soit ou non un problème dépend de ce que vous faites avec le texte (par exemple, si l'ordre n'a pas d'importance, ça va, ou si le générateur ajoute du texte au flux dans l'ordre où il sera affiché, ça va) . J'ai un code d'extraction pyPdf en utilisation quotidienne, sans aucun problème.

Tony Meyer
la source
7
pas de support unicode :(
PanosJee
7
pyPdf prend désormais en charge UTF.
lbolla
2
Cette bibliothèque ressemble à des ordures. Tester sur un PDF aléatoire me donne l'erreur "pyPdf.utils.PdfReadError: marqueur EOF introuvable"
Cerin
4
De la question: le texte généré n'avait pas d'espace entre et n'était d'aucune utilité . J'ai utilisé pyPDF et j'ai obtenu le même résultat - le texte est extrait sans espaces entre les mots.
Jordan Reiter
Lorsque j'exécute la fonction page.extractText (), j'obtiens l'erreur 'TypeError: impossible de convertir l'objet' bytes 'en str implicitement' Comment puis-je gérer cela?
juankysmith
21

Vous pouvez également utiliser assez facilement pdfminer comme bibliothèque. Vous avez accès au modèle de contenu du pdf et pouvez créer votre propre extraction de texte. J'ai fait cela pour convertir le contenu pdf en texte séparé par des points-virgules, en utilisant le code ci-dessous.

La fonction trie simplement les objets de contenu TextItem selon leurs coordonnées y et x, et génère des éléments avec la même coordonnée y qu'une seule ligne de texte, en séparant les objets sur la même ligne avec ';' personnages.

En utilisant cette approche, j'ai pu extraire du texte à partir d'un pdf à partir duquel aucun autre outil n'a été en mesure d'extraire du contenu adapté à une analyse plus approfondie. D'autres outils que j'ai essayés incluent pdftotext, ps2ascii et l'outil en ligne pdftextonline.com.

pdfminer est un outil précieux pour le grattage de 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()

MISE À JOUR :

Le code ci-dessus est écrit contre une ancienne version de l'API, voir mon commentaire ci-dessous.

codeape
la source
De quel type de plugins avez-vous besoin pour que ça marche? J'ai téléchargé et installé pdfminer mais ce n'est pas suffisant ...
kxk
1
Le code ci-dessus est écrit par rapport à une ancienne version de PDFminer. L'API a changé dans les versions plus récentes (par exemple, le package est maintenant pdfminer, non pdflib). Je vous suggère de jeter un œil à la source de pdf2txt.pyla source PDFminer, le code ci-dessus a été inspiré par l'ancienne version de ce fichier.
codeape
17

slate est un projet qui rend très simple l'utilisation de PDFMiner depuis une bibliothèque:

>>> with open('example.pdf') as f:
...    doc = slate.PDF(f)
...
>>> doc
[..., ..., ...]
>>> doc[1]
'Text from page 2...'   
Tim McNamara
la source
1
Je reçois une erreur d'importation lors de l'exécution de "importation d'ardoise": {Fichier "C: \ Python33 \ lib \ site-packages \ slate-0.3-py3.3.egg \ slate_ init_ .py", ligne 48, dans <module> ImportError: impossible d'importer le nom PDF} Mais la classe PDF est là! Savez-vous comment résoudre ce problème?
juankysmith
Non, cela semble très étrange. Avez-vous les dépendances?
Tim McNamara
Normalement, je reçois des messages sur les dépendances manquées, dans ce cas, j'obtiens le message classique "importer le fichier d'ardoise" C: \ Python33 \ lib \ site-packages \ slate-0.3-py3.3.egg \ slate_ init_ .py ", ligne 48 , dans <module> ImportError: impossible d'importer le nom PDF "
juankysmith
L'ardoise 0.3 nécessite pdfminer 20110515, selon ce problème GitHub
jabbett
6
Ce package n'est plus géré. Abstenez-vous de l'utiliser. Vous ne pouvez même pas l'utiliser dans Python 3.5
Sivasubramaniam Arunachalam
9

J'avais besoin de convertir un PDF spécifique en texte brut dans un module python. J'ai utilisé PDFMiner 20110515, après avoir lu leur outil pdf2txt.py , j'ai écrit ce simple extrait:

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() 
gonz
la source
1
def to_txt (pdf_path):
Cătălin George Feștilă
si je voulais seulement convertir un certain nombre de pages, comment le ferais-je avec ce code?
psychok7
@ psychok7 Avez-vous essayé d'utiliser l'outil pdf2txt? Il semble prendre en charge cette fonctionnalité dans la version actuelle avec l'indicateur -p, l'implémentation semble facile à suivre et devrait être facile à personnaliser aussi: github.com/euske/pdfminer/blob/master/tools/pdf2txt.py J'espère que cela vous aidera! :)
gonz
1
merci @gonz, j'ai essayé pour tout ce qui précède mais votre solution s'avère parfaite pour moi ,, sortie avec des espaces :)
lazarus
pdf2txt.py est installé ici pour moi:C:\Python27\Scripts\pdfminer\tools\pdf2txt.py
The Red Pea
6

Réutilisation du code pdf2txt.py fourni avec pdfminer; vous pouvez créer une fonction qui prendra un chemin vers le pdf; éventuellement, un type extérieur (txt | html | xml | tag) et opte comme la ligne de commande pdf2txt {'-o': '/path/to/outfile.txt' ...}. Par défaut, vous pouvez appeler:

convert_pdf(path)

Un fichier texte sera créé, un frère sur le système de fichiers au pdf d'origine.

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
Skylar Saveland
la source
1

PDFminer m'a donné peut-être une ligne [page 1 sur 7 ...] sur chaque page d'un fichier pdf que j'ai essayé avec.

La meilleure réponse que j'ai jusqu'à présent est pdftoipe, ou le code c ++ est basé sur Xpdf.

voir ma question pour savoir à quoi ressemble la sortie de pdftoipe.

Sphérinabox
la source
1

De plus, il existe PDFTextStream, une bibliothèque Java commerciale qui peut également être utilisée à partir de Python.

msanders
la source
1

J'ai utilisé pdftohtmlavec l' -xmlargument, lire le résultat avec subprocess.Popen(), qui vous donnera x coord, y coord, largeur, hauteur et police, de chaque extrait de texte dans le pdf. Je pense que c'est ce que 'evince' utilise probablement aussi parce que les mêmes messages d'erreur se répandent.

Si vous devez traiter des données en colonnes, cela devient un peu plus compliqué car vous devez inventer un algorithme qui convient à votre fichier pdf. Le problème est que les programmes qui créent des fichiers PDF ne présentent pas nécessairement le texte dans un format logique. Vous pouvez essayer des algorithmes de tri simples et cela fonctionne parfois, mais il peut y avoir de petits «retardataires» et «errants», des morceaux de texte qui ne sont pas mis dans l'ordre que vous pensiez qu'ils le feraient. Il faut donc faire preuve de créativité.

Il m'a fallu environ 5 heures pour en trouver un pour les fichiers PDF sur lesquels je travaillais. Mais cela fonctionne plutôt bien maintenant. Bonne chance.

Decora
la source