Je recherche de la documentation ou des exemples sur la façon d'extraire du texte d'un fichier PDF en utilisant PDFMiner avec Python.
Il semble que PDFMiner a mis à jour son API et que tous les exemples pertinents que j'ai trouvés contiennent du code obsolète (les classes et les méthodes ont changé). Les bibliothèques que j'ai trouvées qui facilitent l'extraction de texte à partir d'un fichier PDF utilisent l'ancienne syntaxe PDFMiner, donc je ne sais pas comment faire cela.
Dans l'état actuel des choses, je regarde juste le code source pour voir si je peux le comprendre.
python
python-3.x
python-2.7
text-extraction
pdfminer
CanardPuncher
la source
la source
PDFminer
cela ne fonctionne pas avec Python 3.xx Cela pourrait être la raison pour laquelle vous obtenez desimport
erreurs. Vous devriez utiliserpdfminer3k
si c'est le cas, car il s'agit de l'importation Python 3 permanente de ladite bibliothèque.PDFminer
à partir de GitHub et il importe bien. Pouvez-vous publier votre code et publier également votre traçage complet des erreurs?Réponses:
Voici un exemple de travail d'extraction de texte à partir d'un fichier PDF à l'aide de la version actuelle de PDFMiner (septembre 2016)
from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter from pdfminer.converter import TextConverter from pdfminer.layout import LAParams from pdfminer.pdfpage import PDFPage from io import StringIO def convert_pdf_to_txt(path): rsrcmgr = PDFResourceManager() retstr = StringIO() codec = 'utf-8' laparams = LAParams() device = TextConverter(rsrcmgr, retstr, codec=codec, laparams=laparams) fp = open(path, 'rb') interpreter = PDFPageInterpreter(rsrcmgr, device) password = "" maxpages = 0 caching = True pagenos=set() for page in PDFPage.get_pages(fp, pagenos, maxpages=maxpages, password=password,caching=caching, check_extractable=True): interpreter.process_page(page) text = retstr.getvalue() fp.close() device.close() retstr.close() return text
La structure de PDFMiner a changé récemment, donc cela devrait fonctionner pour extraire le texte des fichiers PDF.
Edit : toujours en activité depuis le 7 juin 2018. Vérifié en Python version 3.x
Edit: La solution fonctionne avec Python 3.7 au 3 octobre 2019. J'ai utilisé la bibliothèque Python
pdfminer.six
, publiée en novembre 2018.la source
import sys reload(sys) sys.setdefaultencoding('utf-8')
file(path, 'rb')
en `open (path, 'rb') pour que le mien fonctionne.excellente réponse de DuckPuncher, pour Python3, assurez-vous d'installer pdfminer2 et faites:
import io from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter from pdfminer.converter import TextConverter from pdfminer.layout import LAParams from pdfminer.pdfpage import PDFPage def convert_pdf_to_txt(path): rsrcmgr = PDFResourceManager() retstr = io.StringIO() codec = 'utf-8' laparams = LAParams() device = TextConverter(rsrcmgr, retstr, codec=codec, laparams=laparams) fp = open(path, 'rb') interpreter = PDFPageInterpreter(rsrcmgr, device) password = "" maxpages = 0 caching = True pagenos = set() for page in PDFPage.get_pages(fp, pagenos, maxpages=maxpages, password=password, caching=caching, check_extractable=True): interpreter.process_page(page) fp.close() device.close() text = retstr.getvalue() retstr.close() return text
la source
ImportError:
messageCela fonctionne en mai 2020 en utilisant PDFminer six dans Python3.
Installation du package
Importer le package
from pdfminer.high_level import extract_text
Utilisation d'un PDF enregistré sur disque
text = extract_text('report.pdf')
Ou bien:
with open('report.pdf','rb') as f: text = extract_text(open('report.pdf','rb'))
Utilisation de PDF déjà en mémoire
Si le PDF est déjà en mémoire, par exemple s'il est récupéré sur le Web avec la bibliothèque de requêtes, il peut être converti en flux à l'aide de la
io
bibliothèque:import io response = requests.get(url) text = extract_text(io.BytesIO(response.content))
Performances et fiabilité par rapport à PyPDF2
PDFminer.six fonctionne de manière plus fiable que PyPDF2 (qui échoue avec certains types de PDF), en particulier PDF version 1.7
Cependant, l'extraction de texte avec PDFminer.six est nettement plus lente que PyPDF2 d'un facteur 6.
J'ai chronométré l'extraction de texte avec
timeit
un MBP de 15 "(2018), en chronométrant uniquement la fonction d'extraction (pas d'ouverture de fichier, etc.) avec un PDF de 10 pages et j'ai obtenu les résultats suivants:PDFminer.six: 2.88 sec PyPDF2: 0.45 sec
pdfminer.six a également une empreinte énorme, nécessitant pycryptodome qui a besoin de GCC et d'autres éléments installés poussant une image docker d'installation minimale sur Alpine Linux de 80 Mo à 350 Mo. PyPDF2 n'a pas d'impact notable sur le stockage.
la source
Divulgation complète, je suis l'un des mainteneurs de pdfminer.six.
De nos jours, il existe plusieurs API pour extraire du texte d'un PDF, en fonction de vos besoins. Dans les coulisses, toutes ces API utilisent la même logique pour analyser et analyser la mise en page.
Ligne de commande
Si vous souhaitez extraire du texte une seule fois, vous pouvez utiliser l'outil de ligne de commande pdf2txt.py:
API de haut niveau
Si vous souhaitez extraire du texte avec Python, vous pouvez utiliser l'API de haut niveau. Cette approche est la solution idéale si vous souhaitez extraire du texte par programme à partir de nombreux PDF.
from pdfminer.high_level import extract_text text = extract_text('samples/simple1.pdf')
API composable
Il existe également une API composable qui offre une grande flexibilité dans la gestion des objets résultants. Par exemple, vous pouvez implémenter votre propre algorithme de mise en page en utilisant cela. Cette méthode est suggérée dans les autres réponses, mais je ne la recommanderais que lorsque vous avez besoin de personnaliser le comportement de pdfminer.six.
from io import StringIO from pdfminer.converter import TextConverter from pdfminer.layout import LAParams from pdfminer.pdfdocument import PDFDocument from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter from pdfminer.pdfpage import PDFPage from pdfminer.pdfparser import PDFParser output_string = StringIO() with open('samples/simple1.pdf', 'rb') as in_file: parser = PDFParser(in_file) doc = PDFDocument(parser) rsrcmgr = PDFResourceManager() device = TextConverter(rsrcmgr, output_string, laparams=LAParams()) interpreter = PDFPageInterpreter(rsrcmgr, device) for page in PDFPage.create_pages(doc): interpreter.process_page(page) print(output_string.getvalue())
la source
ce code est testé avec pdfminer pour python 3 (pdfminer-20191125)
from pdfminer.layout import LAParams from pdfminer.converter import PDFPageAggregator from pdfminer.pdfinterp import PDFResourceManager from pdfminer.pdfinterp import PDFPageInterpreter from pdfminer.pdfpage import PDFPage from pdfminer.layout import LTTextBoxHorizontal def parsedocument(document): # convert all horizontal text into a lines list (one entry per line) # document is a file stream lines = [] rsrcmgr = PDFResourceManager() laparams = LAParams() device = PDFPageAggregator(rsrcmgr, laparams=laparams) interpreter = PDFPageInterpreter(rsrcmgr, device) for page in PDFPage.get_pages(document): interpreter.process_page(page) layout = device.get_result() for element in layout: if isinstance(element, LTTextBoxHorizontal): lines.extend(element.get_text().splitlines()) return lines
la source