PDFs analysieren mit qpdf und pikepdf
Wer wissen will, warum ein PDF nicht das tut, was es soll
(ein Tag fehlt, eine Lese-Reihenfolge ist verdreht, ein Span
-Tag verweist ins Leere), kommt um eine Inspektion
auf Objekt-Ebene nicht herum. qpdf
macht den binären
PDF-Inhalt lesbar; pikepdf
macht ihn skriptfähig.
Beide Werkzeuge sind frei und ergänzen sich gut.
Warum PDFs auf Objekt-Ebene inspizieren?
Ein PDF ist im Kern eine geordnete Sammlung von Objekten: Dictionaries,
Streams, Arrays, indirekt referenziert über eine Cross-Reference-Tabelle.
Authoring-Werkzeuge wie Word, InDesign oder LaTeX erzeugen diese
Strukturen aus dem Quelldokument. Wenn etwas im Ergebnis nicht
stimmt, etwa eine Tabelle ohne /Table
-Tag, ein Bild ohne
Alternativtext oder eine Lese-Reihenfolge, die quer durch die Seite
springt, sieht man die Ursache nicht in der grafischen Vorschau.
Sie liegt eine Ebene tiefer.
Hier setzen qpdf und pikepdf an. qpdf ist eine seit 2008 entwickelte C++-Bibliothek mit Kommandozeilen-Werkzeug, die ein PDF in eine sogenannte QDF-Form bringt: dieselbe Datei, nur ohne Komprimierung und mit lesbarem Klartext. pikepdf ist eine Python-Bindings-Schicht genau auf qpdf. Sie erlaubt dasselbe, nur eben aus einem Python-Skript heraus und mit komfortablem Zugriff auf die Objektstruktur.
qpdf: das PDF lesbar machen
qpdf bietet auf der Kommandozeile zwei Operationen, die für die
Inspektion essentiell sind: --qdf
(oft kombiniert mit --object-streams=disable
) und --json
.
Beide arbeiten verlustfrei. Das Ergebnis ist semantisch identisch
zum Original, nur in einer textuellen Form.
qpdf-shell.txt: typische Aufrufe
# 1. Datei in lesbare QDF-Form bringen qpdf --qdf --object-streams=disable input.pdf output.qdf # 2. PDF als JSON-Struktur ausgeben (qpdf 10+) qpdf --json=2 input.pdf > struktur.json # 3. Strukturelle Konsistenz prüfen qpdf --check input.pdf # 4. Einzelne Seiten herauslösen, z. B. zur Mikro-Analyse qpdf --pages input.pdf 1 -- nur-seite-1.pdf
Die QDF-Form ist die schnellste Brücke zur Lesbarkeit. Sie löst Object-Streams auf, dekomprimiert Content-Streams und schreibt jedes Objekt mit lesbaren Zeilenumbrüchen. Wer diese Datei in einem Editor öffnet, findet darin alle Strukturen aus PDF-Aufbau aus Coding-Perspektive wieder: Catalog, StructTreeRoot, Seitenobjekte, Content-Streams. Die offizielle qpdf-Dokumentation beschreibt das in Kapitel 3 „QDF Mode" im Detail.
pikepdf: das PDF skriptfähig machen
pikepdf nutzt qpdf intern und stellt die Objektstruktur als Python-Dictionary-ähnliche Datenstruktur zur Verfügung. Damit lässt sich ein PDF nicht nur lesen, sondern auch gezielt verändern, etwa neue Felder setzen, Tags umordnen oder Metadaten korrigieren, und anschließend in derselben Sitzung wieder schreiben.
pikepdf-basics.py: Datei öffnen und Objekte lesen
import pikepdf # PDF öffnen, als Context-Manager schließt sich die Datei sauber with pikepdf.Pdf.open("input.pdf") as pdf: # Document-Catalog (Wurzelobjekt) holen catalog = pdf.Root print(catalog.keys()) # ['/Type', '/Pages', '/StructTreeRoot', '/MarkInfo', '/Lang', ...] # Sprache (wichtig für Screenreader) korrigieren catalog.Lang = pikepdf.String("de-DE") # MarkInfo prüfen, signalisiert getaggtes PDF mark_info = catalog.MarkInfo print(mark_info.Marked) # True / False # Datei speichern pdf.save("output.pdf")
pikepdf verwaltet die binär codierten PDF-Objekte transparent: Strings werden bei Bedarf automatisch zwischen den PDF-Codierungen und Python umgesetzt, Object-Referenzen lassen sich wie verschachtelte Dictionaries navigieren. Die offizielle Dokumentation auf pikepdf.readthedocs.io beschreibt im Tutorial-Abschnitt „Working with metadata" und „Object model" die wichtigsten Patterns.
Ein Praxis-Workflow: vom Symptom zur Korrektur
In der Praxis folgt die Analyse oft demselben Ablauf, unabhängig davon, ob das Symptom ein PAC-Fehler oder eine veraPDF-Meldung ist:
- qpdf-Check.
Strukturelle Konsistenz prüfen
(
qpdf --check). Wenn schon hier Fehler auftauchen, ist die Datei kaputt. Nichts weiter testen, erst reparieren. - QDF-Form öffnen.
Mit
qpdf --qdfin eine lesbare Form bringen und in einem Editor ansehen. Catalog, StructTreeRoot und betroffene Seite suchen. - Objektbaum traversieren. Mit pikepdf den Struktur-Baum durchlaufen und gezielt die Stelle suchen, an der das Symptom liegt: fehlender Tag, falsche Rolle, leere Alternativtext-Property.
- Gezielt korrigieren. Den betroffenen Knoten mit pikepdf neu setzen und das PDF speichern.
- Validator erneut laufen lassen. Mit veraPDF oder PAC prüfen, ob der Befund verschwunden ist.
Den Struktur-Baum inspizieren
Im Wissensseiten-Strang ist es Schritt 3, die pikepdf-Inspektion,
der konkret werden muss. Die folgenden Code-Schnipsel zeigen ein
typisches Vorgehen: vom StructTreeRoot
aus den Baum
traversieren, alle StructElem
-Knoten sammeln, die
Verteilung der Tag-Rollen prüfen.
tagtree-inspect.py: Rollen-Histogramm
import pikepdf from collections import Counter def walk(node, counts): rolle = str(node.get("/S", "<ohne /S>")) counts[rolle] += 1 kids = node.get("/K", []) if isinstance(kids, pikepdf.Array): for kid in kids: if isinstance(kid, pikepdf.Dictionary): walk(kid, counts) with pikepdf.Pdf.open("input.pdf") as pdf: root = pdf.Root.StructTreeRoot counts = Counter() for kid in root.K: walk(kid, counts) for rolle, anzahl in counts.most_common(): print(f"{rolle}: {anzahl}") # Beispiel-Ausgabe # /P: 47 # /H2: 6 # /Figure: 3 # /Span: 12 # /Document: 1
Schon das Histogramm zeigt typische Befunde: Ein PDF, das laut Layout
eine Tabelle enthält, in dem aber kein /Table
-Knoten
vorkommt, hat das Tagging schlicht nicht. Ein PDF mit /Figure
-Knoten, die kein /Alt
-Property
tragen, scheitert an PDF/UA. Wer hier vor dem Schreiben von
Korrektur-Code zuerst die Verteilung kennt, korrigiert gezielter.
| Aspekt | qpdf (CLI/C++) | pikepdf (Python) |
|---|---|---|
| Schnelle Inspektion | Ja, --qdf
, --json=2
, --check
in Sekunden. |
Möglich, aber Overhead durch Skript-Setup. |
| Skripting / Pipelines | Per Shell-Skript, aber begrenzte Logik. | Volle Python-Logik: Bedingungen, Tests, Schleifen. |
| Objekt-Editor | Nur grobe Operationen (Seiten extrahieren, mergen). | Dictionaries, Arrays, Strings gezielt verändern. |
| Lernkurve | Kommandozeilen-Kenntnisse reichen. | Python-Grundkenntnisse plus PDF-Modell. |
| Performance | Sehr schnell, native C++-Implementierung. | Schnell, gleicher qpdf-Kern, Python-Wrapper-Overhead. |
Grenzen: was qpdf und pikepdf nicht leisten
Beide Werkzeuge sind hervorragend, wenn die Struktur eines PDF inspiziert oder gezielt korrigiert werden soll. Was sie nicht tun, ist genauso wichtig:
- Sie erzeugen keine semantische Bewertung. Ob ein Alternativtext inhaltlich passt, weiß weder qpdf noch pikepdf. Das bleibt menschliche Beurteilung oder die Aufgabe eines Validators wie veraPDF, der wenigstens prüfen kann, ob ein Alt-Text vorhanden ist.
- Sie machen kein OCR. Ein gescanntes PDF ohne Text-Layer bleibt für beide ein Bild. Für OCR brauchst du andere Werkzeuge (Tesseract, Adobe Acrobat, ocrmypdf).
- Sie ersetzen kein PDF/UA-Audit. Sie helfen, konkrete Befunde aus einem Audit gezielt zu reparieren, aber sie ersetzen die Prüfung selbst nicht. Die Quelle der Wahrheit bleibt die ISO-Norm und ihre Validator-Implementierungen.
Drei Annahmen, und warum sie nicht stimmen
Mythos 1: „qpdf repariert kaputte PDFs."
Nur
teilweise. qpdf kann eine PDF-Datei mit beschädigter Cross-Reference-
Tabelle rekonstruieren. Das ist das, was qpdf --check
meldet und was eine spätere Neuausgabe behebt. Inhaltliche
Probleme, fehlende Tags oder falsche Lese-Reihenfolgen sind keine
Strukturkorruption und werden nicht „repariert". Sie müssen
gezielt korrigiert werden.
Mythos 2: „pikepdf ist nur ein Python-Wrapper, also langsam." Falsch. pikepdf bindet die qpdf-C++-Bibliothek über pybind11 ein: die rechenintensiven Operationen laufen nativ. Der Python-Code steuert nur die Logik, nicht die PDF-Verarbeitung selbst. In der Praxis verarbeitet pikepdf auch große Dokumente flüssig.
Mythos 3: „Was Adobe Acrobat anzeigt, ist die Wahrheit über das PDF." Vorsicht. Acrobat interpretiert das PDF nach eigenen Regeln und repariert beim Öffnen still einige Inkonsistenzen. Wer mit qpdf oder pikepdf in die Roh-Datei schaut, sieht den tatsächlichen Zustand, der manchmal von dem abweicht, was Acrobat als Tag-Baum darstellt.
PDF-Pipeline analysieren und sauber stellen?
Wir helfen Entwicklungsteams, bestehende PDF-Produktionsprozesse auf Objekt-Ebene zu analysieren: vom strukturellen Konsistenz-Check über das gezielte Tag-Reparieren bis zur Validator-konformen Auslieferung. Audits einzelner Dokument-Klassen ebenso wie Schulungen für Entwickler:innen-Teams.
Beratung oder Schulung anfragen
