Auslesen von Metadaten aus pdf-Dateien

Code-Stücke können hier veröffentlicht werden.
Benutzeravatar
snafu
User
Beiträge: 6731
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Entstehen diese Fehler bei verschlüsselten PDF-Dateien?
Sirius3
User
Beiträge: 17703
Registriert: Sonntag 21. Oktober 2012, 17:20

@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.
Melewo
User
Beiträge: 320
Registriert: Mittwoch 3. Mai 2017, 16:30

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?
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.

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)
Oder Verzeichnisse durchlaufen:

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() 
Benutzeravatar
snafu
User
Beiträge: 6731
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

@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:

Code: Alles auswählen

extension = os.path.splitext(filename)[1]
if extension.lower() == 'pdf':
    # ...
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.
Melewo
User
Beiträge: 320
Registriert: Mittwoch 3. Mai 2017, 16:30

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.

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
Stimmt, das mit extension.lower() hätte besser ausgesehen und die Liste wäre überflüssig gewesen.
Antworten