Python-Modul zum Konvertieren von PDF in Text [geschlossen]
385
Gibt es ein Python-Modul zum Konvertieren von PDF-Dateien in Text? Ich habe einen in Activestate gefundenen Code ausprobiert, der pypdf verwendet, aber der generierte Text hatte kein Leerzeichen dazwischen und war nutzlos.
Ich suchte nach einer ähnlichen Lösung. Ich muss nur den Text aus der PDF-Datei lesen. Ich brauche die Bilder nicht. pdfminer ist eine gute Wahl, aber ich habe kein einfaches Beispiel zum Extrahieren des Textes gefunden. Endlich habe ich diese SO-Antwort erhalten ( stackoverflow.com/questions/5725278/… ) und benutze sie jetzt.
Nayan
2
Da die Frage geschlossen wurde, habe ich sie auf dem Stack Exchange erneut veröffentlicht, der Softwareempfehlungen gewidmet ist, falls jemand eine neue Antwort schreiben möchte: Python-Modul zum Konvertieren von PDF in Text
Franck Dernoncourt
1
Die einzige Lösung, die für mich für UTF-8-Inhalte funktioniert hat: Apache Tika
Ich habe gerade eine Antwort hinzugefügt, in der beschrieben wird, wie pdfminer als Bibliothek verwendet wird.
Codeape
24
Keine Python 3-Unterstützung :(
Karl Adler
1
Die Antwort, die ich in diesem Thread gegeben habe , kann für Leute nützlich sein, die sich diese Antwort ansehen und sich fragen, wie sie die Bibliothek verwenden sollen. Ich gebe ein Beispiel für die Verwendung der PDFMiner-Bibliothek zum Extrahieren von Text aus dem PDF. Da die Dokumentation etwas spärlich ist, dachte ich, dass es ein paar Leuten helfen könnte.
Hier ist die aktualisierte Version (mit Kommentaren zu dem, was ich geändert / hinzugefügt habe):
def pdf_to_csv(filename):from cStringIO importStringIO#<-- added so you can copy/paste this to try itfrom pdfminer.converter importLTTextItem,TextConverterfrom pdfminer.pdfparser importPDFDocument,PDFParserfrom pdfminer.pdfinterp importPDFResourceManager,PDFPageInterpreterclassCsvConverter(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)#<-- changedfor 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()
Bearbeiten (noch einmal):
Hier ist ein Update für die neueste Version in pypi , 20100619p1. Kurz ersetzt ich LTTextItemmit LTCharund übergeben eine Instanz von LAParams zum CsvConverter Konstruktor.
def pdf_to_csv(filename):from cStringIO importStringIOfrom pdfminer.converter importLTChar,TextConverter#<-- changedfrom pdfminer.layout importLAParamsfrom pdfminer.pdfparser importPDFDocument,PDFParserfrom pdfminer.pdfinterp importPDFResourceManager,PDFPageInterpreterclassCsvConverter(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 isnotNone:
interpreter.process_page(page)
outfp.write("END PAGE %d\n"% i)
device.close()
fp.close()return outfp.getvalue()
BEARBEITEN (noch einmal):
Für die Version aktualisiert 20110515(danke an Oeufcoque Penteano!):
def pdf_to_csv(filename):from cStringIO importStringIOfrom pdfminer.converter importLTChar,TextConverterfrom pdfminer.layout importLAParamsfrom pdfminer.pdfparser importPDFDocument,PDFParserfrom pdfminer.pdfinterp importPDFResourceManager,PDFPageInterpreterclassCsvConverter(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:#<-- changedif isinstance(child,LTChar):(_,_,x,y)= child.bbox
line = lines[int(-y)]
line[x]= child._text.encode(self.codec)#<-- changedfor 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 isnotNone:
interpreter.process_page(page)
outfp.write("END PAGE %d\n"% i)
device.close()
fp.close()return outfp.getvalue()
In [6]: pdfminer importieren In [7]: pdfminer .__ version__ Out [7]: '20100424' In [8]: aus pdfminer.converter LTTextItem importieren LTContainer LTLine LTRect LTTextGroup LITERAL_DEVICE_RGB LTFigur LTPage LTText LTTextLine
Skylar Saveland
@skyl, der obige Code gilt für die vorherige Version '20100213'. Aus der Liste der Änderungen auf ihrer Website, es sieht aus wie sie sich verändert LTTextItemzu LTChar. unixuser.org/~euske/python/pdfminer/index.html#changes
tgray
2
@Oeufcoque Penteano, danke! Ich habe der Antwort für die Version 20110515gemäß Ihrem Kommentar einen weiteren Abschnitt hinzugefügt .
Tgray
1
Die Antwort von @ user3272884 funktioniert vom 5-1-2014
jmunsch
1
Ich musste das gleiche Problem heute lösen, den Code von tgray ein wenig modifizieren, um Informationen über Leerzeichen zu extrahieren, und ihn hier
posten
67
Da keine dieser Lösungen die neueste Version von PDFMiner unterstützt, habe ich eine einfache Lösung geschrieben, die mit PDFMiner den Text eines PDFs zurückgibt. Dies funktioniert für diejenigen, bei denen Importfehler auftretenprocess_pdf
import sys
from pdfminer.pdfinterp importPDFResourceManager,PDFPageInterpreterfrom pdfminer.pdfpage importPDFPagefrom pdfminer.converter importXMLConverter,HTMLConverter,TextConverterfrom pdfminer.layout importLAParamsfrom cStringIO importStringIOdef 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 inPDFPage.get_pages(fp):
interpreter.process_page(page)
data = retstr.getvalue()print data
if __name__ =='__main__':
pdfparser(sys.argv[1])
Siehe folgenden Code, der für Python 3 funktioniert:
import sys
from pdfminer.pdfinterp importPDFResourceManager,PDFPageInterpreterfrom pdfminer.pdfpage importPDFPagefrom pdfminer.converter importXMLConverter,HTMLConverter,TextConverterfrom pdfminer.layout importLAParamsimport 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 inPDFPage.get_pages(fp):
interpreter.process_page(page)
data = retstr.getvalue()print(data)if __name__ =='__main__':
pdfparser(sys.argv[1])
Dies ist das erste Snippet, das ich gefunden habe und das tatsächlich mit seltsamen PDF-Dateien funktioniert (insbesondere mit den kostenlosen E-Books, die man von packtpub bekommen kann). Jeder zweite Code gibt nur das seltsam codierte Rohmaterial zurück, aber Ihr Code gibt tatsächlich Text zurück. Vielen Dank!
Somada141
Sie möchten wahrscheinlich retstr.seek (0) ausführen, nachdem Sie Daten abgerufen haben, oder Sie sammeln Text von allen Seiten.
Tshirtman
2
Um mit zu verwenden python3, muss man neben den offensichtlichen Klammern nach dem printBefehl den fileBefehl durch das Paket ersetzen openund StringIOaus dem Paket importierenio
McLawrence
1
Beeindruckend. Dieser Block hat beim ersten Kopieren perfekt funktioniert. Erstaunlich! Weiter zum Parsen und Korrigieren der Daten und ohne Stress bei der Eingabe.
SecsAndCyber
1
pdfminer funktioniert nicht für python3. Dieser Code funktioniert nicht für pdfminer3k
thang
47
Pdftotext Ein Open-Source-Programm (Teil von Xpdf), das Sie von Python aus aufrufen können (nicht das, wonach Sie gefragt haben, aber möglicherweise nützlich sind). Ich habe es ohne Probleme benutzt. Ich denke, Google verwendet es in Google Desktop.
Dies scheint das nützlichste der hier aufgeführten Tools zu sein, mit der -layoutOption, Text an derselben Position wie im PDF zu halten. Wenn ich nur herausfinden könnte, wie ich den Inhalt einer PDF-Datei darin ableiten kann.
Matthew Schinckel
Nach dem Testen mehrerer Lösungen scheint diese die einfachste und robusteste Option zu sein. Kann von Python einfach mit einem Tempfile umbrochen werden, um zu bestimmen, wohin die Ausgabe geschrieben wird.
Cerin
Cerin , verwenden Sie '-' als Dateinamen, um die Ausgabe an stdout umzuleiten. Auf diese Weise können Sie einfache subprocess.check_output verwenden, und dieser Aufruf würde sich wie eine interne Funktion anfühlen.
Strg-C
Nur um jeden zu verstärken, der es benutzt. . . pdftotextscheint sehr gut zu funktionieren, aber es braucht ein zweites Argument, das ein Bindestrich ist, wenn Sie die Ergebnisse auf stdout sehen wollen.
Gordon Linoff
1
Dadurch werden alle PDF-Dateien ab dem aktuellen Ordner rekursiv konvertiert: find . -iname "*.pdf" -exec pdftotext -enc UTF-8 -eol unix -raw {} \;Standardmäßig nehmen die generierten Dateien den ursprünglichen Namen mit der .txtErweiterung an.
ccpizza
43
pyPDF funktioniert einwandfrei (vorausgesetzt, Sie arbeiten mit wohlgeformten PDFs). Wenn Sie nur den Text (mit Leerzeichen) möchten, können Sie einfach Folgendes tun:
import pyPdf
pdf = pyPdf.PdfFileReader(open(filename,"rb"))for page in pdf.pages:print page.extractText()
Sie können auch problemlos auf Metadaten, Bilddaten usw. zugreifen.
Ein Kommentar im Code "extractText" enthält folgende Hinweise:
Suchen Sie alle Textzeichnungsbefehle in der Reihenfolge, in der sie im Inhaltsdatenstrom angegeben sind, und extrahieren Sie den Text. Dies funktioniert für einige PDF-Dateien gut, für andere jedoch schlecht, je nach verwendetem Generator. Dies wird in Zukunft verfeinert. Verlassen Sie sich nicht auf die Reihenfolge des Texts, der aus dieser Funktion kommt, da sich dieser ändert, wenn diese Funktion komplexer wird.
Ob dies ein Problem ist oder nicht, hängt davon ab, was Sie mit dem Text tun (z. B. wenn die Reihenfolge keine Rolle spielt, ist es in Ordnung, oder wenn der Generator dem Stream Text in der Reihenfolge hinzufügt, in der er angezeigt wird, ist es in Ordnung). . Ich habe pyPdf-Extraktionscode im täglichen Gebrauch, ohne Probleme.
Diese Bibliothek sieht aus wie Müll. Das Testen auf einem zufälligen PDF gibt mir den Fehler "pyPdf.utils.PdfReadError: EOF-Marker nicht gefunden"
Cerin
4
Aus der Frage: Der generierte Text hatte keinen Abstand dazwischen und war nutzlos . Ich habe pyPDF verwendet und das gleiche Ergebnis erzielt - Text wird ohne Leerzeichen zwischen Wörtern extrahiert.
Jordan Reiter
Wenn ich die Funktion page.extractText () ausführe, wird der Fehler 'TypeError: Objekt' Bytes 'kann nicht implizit in str konvertiert werden' angezeigt. Wie kann ich damit umgehen?
Juankysmith
21
Sie können pdfminer auch ganz einfach als Bibliothek verwenden. Sie haben Zugriff auf das Inhaltsmodell des PDFs und können Ihre eigene Textextraktion erstellen. Ich habe dies getan, um PDF-Inhalte mit dem folgenden Code in durch Semikolon getrennten Text zu konvertieren.
Die Funktion sortiert die TextItem-Inhaltsobjekte einfach nach ihren y- und x-Koordinaten und gibt Elemente mit derselben y-Koordinate wie eine Textzeile aus, wobei die Objekte in derselben Zeile mit ';' getrennt werden. Figuren.
Mit diesem Ansatz konnte ich Text aus einem PDF extrahieren, aus dem kein anderes Tool Inhalte extrahieren konnte, die zum weiteren Parsen geeignet waren. Andere Tools, die ich ausprobiert habe, sind pdftotext, ps2ascii und das Online-Tool pdftextonline.com.
pdfminer ist ein unschätzbares Werkzeug für das PDF-Scraping.
def pdf_to_csv(filename):from pdflib.page importTextItem,TextConverterfrom pdflib.pdfparser importPDFDocument,PDFParserfrom pdflib.pdfinterp importPDFResourceManager,PDFPageInterpreterclassCsvConverter(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 :
Der obige Code wurde gegen eine alte Version der API geschrieben, siehe meinen Kommentar unten.
Welche Art von Plugins brauchst du, damit das funktioniert? Ich habe pdfminer heruntergeladen und installiert, aber es ist nicht genug ...
kxk
1
Der obige Code wurde gegen eine alte Version von PDFminer geschrieben. Die API wurde in neueren Versionen geändert (zum Beispiel ist das Paket jetzt pdfminernicht mehr pdflib). Ich schlage vor, Sie werfen einen Blick auf die Quelle pdf2txt.pyin der PDFminer-Quelle. Der obige Code wurde von der alten Version dieser Datei inspiriert.
Codeape
17
slate ist ein Projekt, das die Verwendung von PDFMiner aus einer Bibliothek sehr einfach macht:
Beim Ausführen von "import slate" wird ein Importfehler angezeigt: {Datei "C: \ Python33 \ lib \ site-packages \ slate-0.3-py3.3.egg \ slate_ init_ .py", Zeile 48, in <Modul> ImportError: Name PDF kann nicht importiert werden} Aber die PDF-Klasse ist da! Wissen Sie, wie man das löst?
Juankysmith
Nein, das klingt sehr seltsam. Haben Sie die Abhängigkeiten?
Tim McNamara
Normalerweise erhalte ich Nachrichten über verpasste Abhängigkeiten. In diesem Fall erhalte ich die klassische Nachricht "Schieferdatei importieren" C: \ Python33 \ lib \ site-packages \ slate-0.3-py3.3.egg \ slate_ init_ .py ", Zeile 48 , in <Modul> ImportError: Name PDF kann nicht importiert werden "
Juankysmith
Slate 0.3 erfordert pdfminer 20110515, gemäß dieser GitHub-Ausgabe
jabbett
6
Dieses Paket wird nicht mehr gepflegt. Verwenden Sie es nicht. Sie können es nicht einmal in Python 3.5
Sivasubramaniam Arunachalam
9
Ich musste eine bestimmte PDF-Datei innerhalb eines Python-Moduls in einfachen Text konvertieren. Ich habe PDFMiner 20110515 verwendet, nachdem ich das Tool pdf2txt.py gelesen hatte , habe ich dieses einfache Snippet geschrieben:
Wenn ich nur eine bestimmte Anzahl von Seiten konvertieren wollte, wie würde ich das mit diesem Code machen?
Psychok7
@ psychok7 Haben Sie versucht, das Tool pdf2txt zu verwenden? Es scheint diese Funktion in der aktuellen Version mit dem Flag -p zu unterstützen. Die Implementierung scheint einfach zu folgen und sollte auch leicht anzupassen sein: github.com/euske/pdfminer/blob/master/tools/pdf2txt.py Hoffe, es hilft! :)
Gonz
1
Danke @gonz, ich habe alles versucht, aber Ihre Lösung hat sich als perfekt für mich herausgestellt. Ausgabe mit Leerzeichen :)
Lazarus
pdf2txt.py ist hier für mich installiert:C:\Python27\Scripts\pdfminer\tools\pdf2txt.py
Die rote Erbse
6
Umnutzung des mit pdfminer gelieferten Codes pdf2txt.py; Sie können eine Funktion erstellen, die einen Pfad zum PDF nimmt. Optional ein Outtype (txt | html | xml | tag) und Optionen wie die Befehlszeile pdf2txt {'-o': '/path/to/outfile.txt' ...}. Standardmäßig können Sie Folgendes aufrufen:
convert_pdf(path)
Es wird eine Textdatei erstellt, ein Geschwister im Dateisystem zum Original-PDF.
def convert_pdf(path, outtype='txt', opts={}):import sys
from pdfminer.pdfinterp importPDFResourceManager,PDFPageInterpreter, process_pdf
from pdfminer.converter importXMLConverter,HTMLConverter,TextConverter,TagExtractorfrom pdfminer.layout importLAParamsfrom pdfminer.pdfparser importPDFDocument,PDFParserfrom pdfminer.pdfdevice importPDFDevicefrom pdfminer.cmapdb importCMapDB
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 +=1elif k =='-p': pagenos.update( int(x)-1for x in v.split(','))elif k =='-m': maxpages = int(v)elif k =='-P': password = v
elif k =='-o': outfile = v
elif k =='-n': laparams =Noneelif k =='-A': laparams.all_texts =Trueelif 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()ifnot 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
Ich habe verwendet pdftohtmlmit dem -xmlArgument, lesen Sie das Ergebnis mit subprocess.Popen(), das Ihnen x coord, y - Koordinaten zum Runterladen, Breite, Höhe und Schriftart, jeder Schnipsel des Textes im pdf. Ich denke, das ist es, was 'evince' wahrscheinlich auch verwendet, weil die gleichen Fehlermeldungen ausgegeben werden.
Wenn Sie Säulendaten verarbeiten müssen, wird dies etwas komplizierter, da Sie einen Algorithmus erfinden müssen, der zu Ihrer PDF-Datei passt. Das Problem ist, dass die Programme, die PDF-Dateien erstellen, den Text nicht unbedingt in einem logischen Format auslegen. Sie können einfache Sortieralgorithmen ausprobieren und es funktioniert manchmal, aber es kann kleine "Nachzügler" und "Streuner" geben, Textteile, die nicht in der Reihenfolge angeordnet werden, in der Sie sie erwartet haben. Man muss also kreativ werden.
Ich brauchte ungefähr 5 Stunden, um eines für die PDFs herauszufinden, an denen ich arbeitete. Aber jetzt funktioniert es ziemlich gut. Viel Glück.
Antworten:
Probieren Sie PDFMiner aus . Es kann Text aus PDF-Dateien im HTML-, SGML- oder "Tagged PDF" -Format extrahieren.
Das Tagged PDF-Format scheint das sauberste zu sein, und wenn Sie die XML-Tags entfernen, bleibt nur der bloße Text übrig.
Eine Python 3-Version ist verfügbar unter:
quelle
Das PDFMiner- Paket hat sich seit der Veröffentlichung von codeape geändert .
BEARBEITEN (erneut):
PDFMiner wurde in der Version erneut aktualisiert
20100213
Sie können die installierte Version folgendermaßen überprüfen:
Hier ist die aktualisierte Version (mit Kommentaren zu dem, was ich geändert / hinzugefügt habe):
Bearbeiten (noch einmal):
Hier ist ein Update für die neueste Version in pypi ,
20100619p1
. Kurz ersetzt ichLTTextItem
mitLTChar
und übergeben eine Instanz von LAParams zum CsvConverter Konstruktor.BEARBEITEN (noch einmal):
Für die Version aktualisiert
20110515
(danke an Oeufcoque Penteano!):quelle
LTTextItem
zuLTChar
. unixuser.org/~euske/python/pdfminer/index.html#changes20110515
gemäß Ihrem Kommentar einen weiteren Abschnitt hinzugefügt .Da keine dieser Lösungen die neueste Version von PDFMiner unterstützt, habe ich eine einfache Lösung geschrieben, die mit PDFMiner den Text eines PDFs zurückgibt. Dies funktioniert für diejenigen, bei denen Importfehler auftreten
process_pdf
Siehe folgenden Code, der für Python 3 funktioniert:
quelle
python3
, muss man neben den offensichtlichen Klammern nach demprint
Befehl denfile
Befehl durch das Paket ersetzenopen
undStringIO
aus dem Paket importierenio
Pdftotext Ein Open-Source-Programm (Teil von Xpdf), das Sie von Python aus aufrufen können (nicht das, wonach Sie gefragt haben, aber möglicherweise nützlich sind). Ich habe es ohne Probleme benutzt. Ich denke, Google verwendet es in Google Desktop.
quelle
-layout
Option, Text an derselben Position wie im PDF zu halten. Wenn ich nur herausfinden könnte, wie ich den Inhalt einer PDF-Datei darin ableiten kann.pdftotext
scheint sehr gut zu funktionieren, aber es braucht ein zweites Argument, das ein Bindestrich ist, wenn Sie die Ergebnisse auf stdout sehen wollen.find . -iname "*.pdf" -exec pdftotext -enc UTF-8 -eol unix -raw {} \;
Standardmäßig nehmen die generierten Dateien den ursprünglichen Namen mit der.txt
Erweiterung an.pyPDF funktioniert einwandfrei (vorausgesetzt, Sie arbeiten mit wohlgeformten PDFs). Wenn Sie nur den Text (mit Leerzeichen) möchten, können Sie einfach Folgendes tun:
Sie können auch problemlos auf Metadaten, Bilddaten usw. zugreifen.
Ein Kommentar im Code "extractText" enthält folgende Hinweise:
Ob dies ein Problem ist oder nicht, hängt davon ab, was Sie mit dem Text tun (z. B. wenn die Reihenfolge keine Rolle spielt, ist es in Ordnung, oder wenn der Generator dem Stream Text in der Reihenfolge hinzufügt, in der er angezeigt wird, ist es in Ordnung). . Ich habe pyPdf-Extraktionscode im täglichen Gebrauch, ohne Probleme.
quelle
Sie können pdfminer auch ganz einfach als Bibliothek verwenden. Sie haben Zugriff auf das Inhaltsmodell des PDFs und können Ihre eigene Textextraktion erstellen. Ich habe dies getan, um PDF-Inhalte mit dem folgenden Code in durch Semikolon getrennten Text zu konvertieren.
Die Funktion sortiert die TextItem-Inhaltsobjekte einfach nach ihren y- und x-Koordinaten und gibt Elemente mit derselben y-Koordinate wie eine Textzeile aus, wobei die Objekte in derselben Zeile mit ';' getrennt werden. Figuren.
Mit diesem Ansatz konnte ich Text aus einem PDF extrahieren, aus dem kein anderes Tool Inhalte extrahieren konnte, die zum weiteren Parsen geeignet waren. Andere Tools, die ich ausprobiert habe, sind pdftotext, ps2ascii und das Online-Tool pdftextonline.com.
pdfminer ist ein unschätzbares Werkzeug für das PDF-Scraping.
UPDATE :
Der obige Code wurde gegen eine alte Version der API geschrieben, siehe meinen Kommentar unten.
quelle
pdfminer
nicht mehrpdflib
). Ich schlage vor, Sie werfen einen Blick auf die Quellepdf2txt.py
in der PDFminer-Quelle. Der obige Code wurde von der alten Version dieser Datei inspiriert.slate
ist ein Projekt, das die Verwendung von PDFMiner aus einer Bibliothek sehr einfach macht:quelle
Ich musste eine bestimmte PDF-Datei innerhalb eines Python-Moduls in einfachen Text konvertieren. Ich habe PDFMiner 20110515 verwendet, nachdem ich das Tool pdf2txt.py gelesen hatte , habe ich dieses einfache Snippet geschrieben:
quelle
C:\Python27\Scripts\pdfminer\tools\pdf2txt.py
Umnutzung des mit pdfminer gelieferten Codes pdf2txt.py; Sie können eine Funktion erstellen, die einen Pfad zum PDF nimmt. Optional ein Outtype (txt | html | xml | tag) und Optionen wie die Befehlszeile pdf2txt {'-o': '/path/to/outfile.txt' ...}. Standardmäßig können Sie Folgendes aufrufen:
Es wird eine Textdatei erstellt, ein Geschwister im Dateisystem zum Original-PDF.
quelle
PDFminer gab mir vielleicht eine Zeile [Seite 1 von 7 ...] auf jeder Seite einer PDF-Datei, die ich damit ausprobiert habe.
Die beste Antwort, die ich bisher habe, ist pdftoipe oder der C ++ - Code, der auf Xpdf basiert.
Siehe meine Frage, wie die Ausgabe von pdftoipe aussieht.
quelle
Zusätzlich gibt es PDFTextStream , eine kommerzielle Java-Bibliothek, die auch von Python aus verwendet werden kann.
quelle
Ich habe verwendet
pdftohtml
mit dem-xml
Argument, lesen Sie das Ergebnis mitsubprocess.Popen()
, das Ihnen x coord, y - Koordinaten zum Runterladen, Breite, Höhe und Schriftart, jeder Schnipsel des Textes im pdf. Ich denke, das ist es, was 'evince' wahrscheinlich auch verwendet, weil die gleichen Fehlermeldungen ausgegeben werden.Wenn Sie Säulendaten verarbeiten müssen, wird dies etwas komplizierter, da Sie einen Algorithmus erfinden müssen, der zu Ihrer PDF-Datei passt. Das Problem ist, dass die Programme, die PDF-Dateien erstellen, den Text nicht unbedingt in einem logischen Format auslegen. Sie können einfache Sortieralgorithmen ausprobieren und es funktioniert manchmal, aber es kann kleine "Nachzügler" und "Streuner" geben, Textteile, die nicht in der Reihenfolge angeordnet werden, in der Sie sie erwartet haben. Man muss also kreativ werden.
Ich brauchte ungefähr 5 Stunden, um eines für die PDFs herauszufinden, an denen ich arbeitete. Aber jetzt funktioniert es ziemlich gut. Viel Glück.
quelle
Habe diese Lösung heute gefunden. Funktioniert gut für mich. Sogar das Rendern von PDF-Seiten in PNG-Bilder. http://www.swftools.org/gfx_tutorial.html
quelle