Auslesen von Metadaten aus pdf-Dateien
Hier noch die Fehlermeldung:
Traceback (most recent call last):
File "C:/Users/User/PycharmProjects/untitled/Schreibtest.py", line 41, in <module>
read_pdf = PyPDF2.PdfFileReader(pdf_file)
File "C:\Users\User\AppData\Local\Programs\Python\Python36\lib\site-packages\PyPDF2\pdf.py", line 1084, in __init__
self.read(stream)
File "C:\Users\User\AppData\Local\Programs\Python\Python36\lib\site-packages\PyPDF2\pdf.py", line 1697, in read
line = self.readNextEndLine(stream)
File "C:\Users\User\AppData\Local\Programs\Python\Python36\lib\site-packages\PyPDF2\pdf.py", line 1937, in readNextEndLine
raise utils.PdfReadError("Could not read malformed PDF file")
PyPDF2.utils.PdfReadError: Could not read malformed PDF file
Process finished with exit code 1
Was läuft hier falsch?
Traceback (most recent call last):
File "C:/Users/User/PycharmProjects/untitled/Schreibtest.py", line 41, in <module>
read_pdf = PyPDF2.PdfFileReader(pdf_file)
File "C:\Users\User\AppData\Local\Programs\Python\Python36\lib\site-packages\PyPDF2\pdf.py", line 1084, in __init__
self.read(stream)
File "C:\Users\User\AppData\Local\Programs\Python\Python36\lib\site-packages\PyPDF2\pdf.py", line 1697, in read
line = self.readNextEndLine(stream)
File "C:\Users\User\AppData\Local\Programs\Python\Python36\lib\site-packages\PyPDF2\pdf.py", line 1937, in readNextEndLine
raise utils.PdfReadError("Could not read malformed PDF file")
PyPDF2.utils.PdfReadError: Could not read malformed PDF file
Process finished with exit code 1
Was läuft hier falsch?
Mittlerweile habe ich die Verzeichnisse noch einmal aufgeräumt (nur noch pdfs). Wenn ich nun das Programm kompiliere, bekomme ich die folgende Fehlermeldung:
Traceback (most recent call last):
File "C:/Users/User/PycharmProjects/untitled/Schreibtest.py", line 60, in <module>
num_pages = read_pdf.trailer["/Root"]["/Pages"]["/Count"]
File "C:\Users\User\AppData\Local\Programs\Python\Python36\lib\site-packages\PyPDF2\generic.py", line 516, in __getitem__
return dict.__getitem__(self, key).getObject()
File "C:\Users\user\AppData\Local\Programs\Python\Python36\lib\site-packages\PyPDF2\generic.py", line 178, in getObject
return self.pdf.getObject(self).getObject()
File "C:\Users\user\AppData\Local\Programs\Python\Python36\lib\site-packages\PyPDF2\pdf.py", line 1593, in getObject
retval = self._getObjectFromStream(indirectReference)
File "C:\Users\user\AppData\Local\Programs\Python\Python36\lib\site-packages\PyPDF2\pdf.py", line 1543, in _getObjectFromStream
streamData = BytesIO(b_(objStm.getData()))
File "C:\Users\user\AppData\Local\Programs\Python\Python36\lib\site-packages\PyPDF2\generic.py", line 841, in getData
decoded._data = filters.decodeStreamData(self)
File "C:\Users\user\AppData\Local\Programs\Python\Python36\lib\site-packages\PyPDF2\filters.py", line 346, in decodeStreamData
data = FlateDecode.decode(data, stream.get("/DecodeParms"))
File "C:\Users\user\AppData\Local\Programs\Python\Python36\lib\site-packages\PyPDF2\filters.py", line 111, in decode
data = decompress(data)
File "C:\Users\user\AppData\Local\Programs\Python\Python36\lib\site-packages\PyPDF2\filters.py", line 49, in decompress
return zlib.decompress(data)
zlib.error: Error -3 while decompressing data: incorrect header check
Process finished with exit code 1
Muss ich noch ein Paket zlib integrieren? Wer hat eine Idee was hier falsch ist? Gibt es eine Alternative zu PyPDF2 zum Auslesen von PDF Metadaten wie Seitenzahl etc.?
Traceback (most recent call last):
File "C:/Users/User/PycharmProjects/untitled/Schreibtest.py", line 60, in <module>
num_pages = read_pdf.trailer["/Root"]["/Pages"]["/Count"]
File "C:\Users\User\AppData\Local\Programs\Python\Python36\lib\site-packages\PyPDF2\generic.py", line 516, in __getitem__
return dict.__getitem__(self, key).getObject()
File "C:\Users\user\AppData\Local\Programs\Python\Python36\lib\site-packages\PyPDF2\generic.py", line 178, in getObject
return self.pdf.getObject(self).getObject()
File "C:\Users\user\AppData\Local\Programs\Python\Python36\lib\site-packages\PyPDF2\pdf.py", line 1593, in getObject
retval = self._getObjectFromStream(indirectReference)
File "C:\Users\user\AppData\Local\Programs\Python\Python36\lib\site-packages\PyPDF2\pdf.py", line 1543, in _getObjectFromStream
streamData = BytesIO(b_(objStm.getData()))
File "C:\Users\user\AppData\Local\Programs\Python\Python36\lib\site-packages\PyPDF2\generic.py", line 841, in getData
decoded._data = filters.decodeStreamData(self)
File "C:\Users\user\AppData\Local\Programs\Python\Python36\lib\site-packages\PyPDF2\filters.py", line 346, in decodeStreamData
data = FlateDecode.decode(data, stream.get("/DecodeParms"))
File "C:\Users\user\AppData\Local\Programs\Python\Python36\lib\site-packages\PyPDF2\filters.py", line 111, in decode
data = decompress(data)
File "C:\Users\user\AppData\Local\Programs\Python\Python36\lib\site-packages\PyPDF2\filters.py", line 49, in decompress
return zlib.decompress(data)
zlib.error: Error -3 while decompressing data: incorrect header check
Process finished with exit code 1
Muss ich noch ein Paket zlib integrieren? Wer hat eine Idee was hier falsch ist? Gibt es eine Alternative zu PyPDF2 zum Auslesen von PDF Metadaten wie Seitenzahl etc.?
@TuXX: ich habe das Gefühl, dass Du Dich gar nicht mit dem Problem beschäftigen willst, sondern immer nur die nächste Fehlermeldung schicktst, die Du bekommst. Erster Schritt wäre, zu schauen, ob es sich überhaupt um eine korrekte PDF-Datei handelt. Falls ja, könnte es sein, dass es sich um ein PDF handelt, bei dem die Meta-Informationen auch in einem verschlüsselten Stream liegen, dann hast Du natürlich ohne Passwort Pech gehabt.
Verschlüsselte PDFs habe ich nicht zu liegen, da kann ich nichts zu sagen. Doch was liefert Dein Script für Pfade und was ist in "gespfad" enthalten. Danach wurde bereits gefragt und eine Antwort hast Du nicht geliefert.TuXX hat geschrieben:Mittlerweile bin ich einen kleinen Schritt vorangekommen. Wenn ich einen festen Pfad eingebe kann ich die Anzahl der Seiten auslesen:
pdf_file = open(r'C:\Users\rogbet\Desktop\Problembeschreibung.pdf', 'rb')
read_pdf = PyPDF2.PdfFileReader(pdf_file)
number_of_pages = read_pdf.getNumPages()
print(number_of_pages)
Was nachwievor nicht funktioniert ist das Zählen von Seiten für mittels Skript ermittelte Pfade. Der bisherige Code sieht wie folgt aus:
gespfad = os.path.join(folderName,filename)
pdf_file = open(gespfad, 'rb')
read_pdf = PyPDF2.PdfFileReader(pdf_file)
number_of_pages = read_pdf.getNumPages()
print(number_of_pages)
Bei der Kompilierung werden Fehler angezeigt. Weiss jemand was hier schief läuft?
Wie sehen Deine Schleifen aus und was hat "open" da verloren, wenn Du nur die Seiten zählen möchtest? Habe ein paar Varianten getestet und die Seitenzahlen lassen sich gut zählen, ohne dass da etwas mit open eingelesen oder geöffnet werden soll, das macht wohl der Reader von sich aus, nehme ich an.
Das mit normcase im ersten Beispiel könnte man wohl auch noch weglassen, ich schreibe es halt mit.
Die beiden anderen Beispiele ließen sich vielleicht noch besser schreiben, doch die laufen zumindest und erfüllen ihren Zweck.
Eine einzelne Datei:
Code: Alles auswählen
from PyPDF2 import PdfFileReader
import os
pdf_file = os.path.normcase("C:/.../datei.pdf")
read_pdf = PdfFileReader(pdf_file)
number_of_pages = read_pdf.getNumPages()
print(number_of_pages)
Code: Alles auswählen
from PyPDF2 import PdfFileReader
import os
# Ab der Verzeichnisebene auf dem das Script liegt
def liefere_seitenzahlen():
endungen = [".pdf",".PDF"]
for root, dirs, files in os.walk("."):
for name in files:
extension = os.path.splitext(name)[1]
if extension in endungen:
read_pdf = PdfFileReader(os.path.join(root, name))
number_of_pages = read_pdf.getNumPages()
print("Datei: {} - Seiten: {}".format(name, number_of_pages))
if __name__ == "__main__":
liefere_seitenzahlen()
Code: Alles auswählen
from PyPDF2 import PdfFileReader
import os
# Ab der Verzeichnisebene auf dem das Script liegt mit kompletten Pfaden.
def liefere_seitenzahlen():
pfad = os.path.abspath(".")
endungen = [".pdf",".PDF"]
for root, dirs, files in os.walk("."):
for name in files:
extension = os.path.splitext(name)[1]
if extension in endungen:
komplett = os.path.join(pfad, os.path.relpath(root), name)
read_pdf = PdfFileReader(komplett)
number_of_pages = read_pdf.getNumPages()
print("Kompletter Pfad: {} - Seiten: {}"
.format(komplett, number_of_pages))
if __name__ == "__main__":
liefere_seitenzahlen()
@Melewo:
normcase() ist in diesem Zusammenhang unnötig. Denn es drückt ja die Bedeutung eines relativen Pfades vom aktuellen Standort im Dateisystem als absolute Pfadangabe aus. Das ist sinnvoll, wenn man die Pfadangabe von einem anderen Ort im Dateisystem benutzen möchte. Oder manchmal auch, wenn man den Pfad für den Benutzer anzeigen will. Wenn man das aber quasi nur für den internen Bereich benutzt, ohne das sich der Standort im Dateisystem geändert hat, dann ist es im Endeffekt das selbe wie die relative Angabe.
Und das Prüfen auf eine PDF-Endung für den Dateinamen würde ich so machen:
Dann hat man alle denkbaren Schreibweisen abgedeckt und braucht keine Liste dafür.
EDIT:
Das mit der absoluten Angabe bei normase() stimmt nicht mal. Macht es beim internen Gebrauch jedoch nicht weniger überflüssig.
normcase() ist in diesem Zusammenhang unnötig. Denn es drückt ja die Bedeutung eines relativen Pfades vom aktuellen Standort im Dateisystem als absolute Pfadangabe aus. Das ist sinnvoll, wenn man die Pfadangabe von einem anderen Ort im Dateisystem benutzen möchte. Oder manchmal auch, wenn man den Pfad für den Benutzer anzeigen will. Wenn man das aber quasi nur für den internen Bereich benutzt, ohne das sich der Standort im Dateisystem geändert hat, dann ist es im Endeffekt das selbe wie die relative Angabe.
Und das Prüfen auf eine PDF-Endung für den Dateinamen würde ich so machen:
Code: Alles auswählen
extension = os.path.splitext(filename)[1]
if extension.lower() == 'pdf':
# ...
EDIT:
Das mit der absoluten Angabe bei normase() stimmt nicht mal. Macht es beim internen Gebrauch jedoch nicht weniger überflüssig.
Ja, das mit normcase sehe ich ein. Ich benutze es nur, weil es dann unter Windows die Slashes in Backslashes umwandelt, ohne dass man die allein so schreiben müsste und dann mit einem zweiten Backslash \\ maskieren. Aber ich weiß, Windows liest die auch richtig, wenn man die nur als einfache / Slashes schreibt.
Stimmt, das mit extension.lower() hätte besser ausgesehen und die Liste wäre überflüssig gewesen.
Code: Alles auswählen
import os
pdf_file = os.path.normcase("C:/verzeichnis/verzeichnis/datei.pdf")
print(pdf_file)
# Ausgabe:
# c:\verzeichnis\verzeichnis\datei.pdf