15 Punkte von GN⁺ 2025-08-04 | 5 Kommentare | Auf WhatsApp teilen
  • PDF-Parsing sollte auf einer klaren Reihenfolge und Struktur basieren, doch reale Dateien halten sich oft nicht an diese Vorgaben
  • Bei Cross-Reference-(xref-)Zeigern und beim Finden von Offsets treten verschiedene Fehler und Inkonsistenzen auf
  • In der Praxis entstehen viele Probleme durch unnötige Daten vor dem PDF-Header oder durch falsch platzierte Zeiger und Offsets
  • Es gibt auch viele Fälle, in denen die xref-Tabelle selbst unklar oder fehlerhaft formatiert ist
  • Deshalb implementieren große Viewer zusätzliche Logik, um auch nicht standardkonforme PDF-Dateien zu unterstützen

Ein idealer Ansatz für das PDF-Parsing

  • PDF-Parsing läuft theoretisch in festen Schritten ab
    • Am Dateianfang wird der Kommentar mit dem Versions-Header gesucht
    • Der Cross-Reference-(xref-)Zeiger wird gefunden
    • Alle Objekt-Offsets werden gesammelt
    • Das trailer-Dictionary wird gefunden, um auf die gesamte Katalogstruktur zuzugreifen

Einführung in PDF-Objekte

  • PDF-Objekte sind Einheiten, die Zahlen, Strings, Dictionaries und andere PDF-Elemente kapseln und speichern
  • Jedes Objekt befindet sich zwischen den Markern "obj/endobj"
  • Objekte sind über indirekte Referenzen (indirect reference, z. B. "16 0 R") miteinander verbunden
  • Wie Objekte in der Datei verteilt sind, ist flexibel, aber einige Objekttypen müssen zwingend indirekt referenziert werden

Cross-Reference-Offsets finden

  • Ein PDF enthält strukturell eine Cross-Reference-(xref-)Tabelle, die als Index für Objektpositionen dient
  • Am Dateiende wird mit der Syntax "startxref" eine bestimmte Byte-Position als Zeiger angegeben
  • Dieser Zeiger bestimmt die xref-Position, aber zwischen Spezifikation und realen Dateien gibt es Unterschiede. Zum Beispiel sollte der Marker "%EOF" eigentlich in der letzten Zeile stehen, in realen PDFs kann er jedoch irgendwo innerhalb der letzten 1.024 Byte auftauchen
  • In realen Dateien finden sich verschiedene Abweichungen wie Formatfehler beim Zeiger (startref usw.) oder fehlende Zeilenumbrüche

Objekt-Offsets finden

  • In der xref-Tabelle folgen auf "xref" die Startnummer des Objekts und die Anzahl der Objekte, und Offset/Generationsnummer/Status (n oder f) jedes Objekts werden zeilenweise aufgeführt
  • Es kann mehrere xref-Tabellen geben, die über den /Prev-Eintrag miteinander verknüpft sind

Position des trailer-Dictionarys suchen

  • Oberhalb des startxref-Markers befindet sich das trailer-Dictionary, das die wesentlichen Metadaten enthält, um das Root-Objekt zu finden
  • Ausgehend vom Root-Objekt kann mit der Interpretation der gesamten Struktur begonnen werden

Die Praxis: unerwartete Probleme

  • Viele Dateien halten sich nicht an die PDF-Spezifikation, sodass sie mit einem allgemeinen Parser nur schwer verarbeitet werden können

  • Häufige Fehlschläge bei der Suche nach Cross-Reference-Zeigern

    • Der Zeiger befindet sich nicht am Dateiende oder nicht innerhalb der letzten 1.024 Byte
    • Tippfehler (startref usw.)
    • Ausnahmeformate
  • In einer Untersuchung von 3.977 realen PDF-Beispielen hatten etwa 0,5 % Fehler in der xref-Deklaration

PDF-Inhalt beginnt bei einem Offset ungleich 0

  • Wenn sich vor dem Header unnütze Daten (junk) befinden, verschieben sich alle Byte-Offsets, wodurch die startxref-Position nicht mehr stimmt
  • Offsets müssen relativ zur Header-Position neu berechnet werden, und beide Positionen müssen geprüft werden
  • Das macht etwa 50 % aller Fehler aus

Der xref-Zeiger zeigt auf die Mitte der xref-Tabelle

  • Der angegebene Offset kann mitten in den Inhalt der xref-Tabelle zeigen
  • In 3.977 Beispielen wurde das etwa 5 Mal beobachtet

Der Zeiger liegt in der Nähe von xref

  • Oft ist der Zeiger nicht exakt korrekt, sondern nur um Leerzeichen oder Zeilenumbruchzeichen direkt vor oder nach xref verschoben

Der Zeiger stimmt, aber die xref-Offsets sind falsch

  • Auch die in der xref-Tabelle eingetragenen Offsets selbst können falsch sein
  • Bei manchen Objekten stimmt der Wert, während andere fehlerhafte Offsets haben

Der erste Zeiger ist korrekt, aber der vorherige Offset (/Prev) ist fehlerhaft

  • In vielen Fällen werden beim Bearbeiten eines PDFs im /Prev-Zeiger falsche Werte gespeichert (z. B. 0)

Das Format der xref-Tabelle ist fehlerhaft

  • Es gibt viele Varianten: "xref" und Zahlen kleben ohne Zeilenumbruch zusammen, es gibt mehr Einträge als deklarierte Objekte, oder mitten in der Tabelle befinden sich Mülldaten
  • Solche Fälle wurden etwa bei PdfPig vielfach als Issues gemeldet

Fazit

  • Laut Spezifikation sollte PDF-Parsing in einer standardisierten Reihenfolge ablaufen, aber viele reale Dateien tun das nicht, wodurch verschiedenste Parsing-Probleme entstehen
  • PDF-Viewer für den praktischen Einsatz enthalten standardmäßig Funktionen zur Unterstützung nicht standardkonformer PDFs
  • Diese Zusammenfassung behandelt nur einen kleinen Teil des Parsings aus der PDF-Spezifikation (22 Seiten von insgesamt 1300 Seiten)

5 Kommentare

 
mhj5730 2025-08-06

Diese Zusammenfassung behandelt nur einen Teil des Parsings, der einem Ausschnitt der PDF-Spezifikation entspricht (22 Seiten von insgesamt 1300 Seiten) <- ... 1300 Seiten sind wirklich enorm ...

 
kaydash 2025-08-05

Wow..

 
spp00 2025-08-05

PDF ist, offen gesagt, ein für Menschen gut lesbares Format, das von Menschen erstellte Formatierungen möglichst weitgehend bewahrt – für Maschinen ist es jedoch denkbar ungeeignet.

 
reagea0 2025-08-05

Kann ich nachvollziehen. Ehrlich gesagt bin ich mir auch nicht sicher, ob es sich gut lesen lässt … Es ist einfach zu schwerfällig und unhandlich.

 
GN⁺ 2025-08-04
Hacker-News-Kommentare
  • Die Antwort ist klar

    1. PDF unterstützt das Anhängen von Metadaten in jedem gewünschten Format
    2. Alle Programme zur PDF-Erstellung müssten dieselben Informationen in einer maschinenlesbaren Form anhängen
    3. Dann müssten Leute, die PDFs parsen wollen, nur auf die Metadaten schauen
      In der Realität heiße ich Geoff, und die Hälfte der Lebenslauf-Parser erkennt meinen Namen getrennt als „Geo“ und „ff“
      Das liegt daran, wie Text in PDFs landet, und ist ein Problem, das bei vielen Quell-Apps immer wieder auftritt
    • PDF-Parsing und das Parsen von PDF-Inhalten sind völlig unterschiedliche Dinge
      Eine PDF-Datei zu parsen ist schon lästig genug, aber PDFs basieren selbst auf „an einer bestimmten Position etwas platzieren“, also nicht auf klar definiertem Text innerhalb von Bounding Boxes, sodass man zur Wortextraktion raten muss, welche Zeichen zusammengehören
      Wenn man Lebenslauf-Parsern helfen will, lohnt sich ein Blick auf den Accessibility tree
      Nicht jeder PDF-Renderer exportiert barrierefreie PDFs, aber barrierefreie PDFs können immerhin helfen, Dinge wie Namen korrekt auszulesen
      Das „ff“-Problem entsteht vermutlich dadurch, dass der Lebenslauf-Analysator Nicht-ASCII-Zeichen nicht verarbeiten kann, etwa die Ligatur ff
      Man kann den PDF-Renderer so einstellen, dass er keine Ligaturen erzeugt, aber dann kann der Text unschön aussehen

    • Es wirkt so, als würde man sehr viel in das Wort „sollte“ hineinlegen
      Wenn die Nutzung von PDFs in der Praxis ziemlich feindselig ist, denken die Leute wohl nicht so weit
      Schon der Grund, einen Lebenslauf als PDF einzureichen, ist oft, zu verhindern, dass Zwischenhändler ihn verändern, und „Bearbeitung“ hat viele Formen, etwa Kästen über ein Bild zu legen, um etwas zu verdecken, oder Tabellen als PDF statt als CSV zu erstellen, damit die Auswertung schwieriger wird

    • In der Praxis funktioniert dieser Ansatz in manchen Fällen durchaus gut, einige Apps verwenden ihn bereits
      Allerdings bleibt das Problem, dass die beiden Darstellungen (Inhalt/Metadaten) in der Realität nicht übereinstimmen müssen

    • Es bleibt die Frage, was man mit eingescannten handschriftlichen Dokumenten oder anderen Scans macht, wenn Scanner und normale Heimcomputer kein perfektes OCR bieten

    • Wahrscheinlich liegt das Problem daran, dass ff als Ligatur gerendert wird

  • Ich bin Gründer von Tensorlake
    Wir haben eine Dokument-Parsing-API für Entwickler gebaut
    Das ist der Grund, warum Computer-Vision-Ansätze beim PDF-Parsing in der Praxis tatsächlich gut funktionieren
    Sich nur auf Metadaten innerhalb der Datei zu verlassen, skaliert bei der Vielfalt an PDF-Quellen nicht
    Deshalb wandeln wir PDFs in Bilder um, wenden zuerst ein Layout-Erkennungsmodell an, lassen dann spezialisierte Modelle für Text- und Tabellenerkennung laufen und setzen die Teile wieder zusammen, um Ergebnisse zu erzielen, die selbst in Bereichen mit hohen Genauigkeitsanforderungen brauchbar sind

    • Auf den ersten Blick wirkt dieser Ansatz etwas albern, aber eigentlich scheint er die realistischste Lösung zu sein
      PDF ist im Kern ein Format, das dafür entwickelt wurde, ein für Menschen lesbares Layout darzustellen, nicht etwas, das für Maschinenlesbarkeit entworfen wurde, sondern ein Format mit Fokus auf ansprechende Darstellung
      Deshalb wirkt ein Ansatz, der die menschliche Art zu lesen nachahmt, ziemlich plausibel
      Schade ist nur, dass PDF in über 30 Jahren keine bessere Maschinenlesbarkeit bekommen hat
      Ich frage mich, welcher Anreiz gefehlt hat, damit das nicht möglich wurde
      Falls jemand dazu Einsichten hat, würde ich sie gern hören

    • Es ist ein wenig ironisch
      Wenn man ein PDF ausdruckt, einscannt und dann per E-Mail verschickt, ist das normalerweise Anlass zum Spott, aber beim PDF-Parsing macht man im Grunde genau dasselbe
      Dass so ein Ansatz nötig ist, ist eine frustrierende Realität
      Die Welt parst HTML schließlich auch nicht auf diese Weise

    • Ich bin Mitgründer von Nutrient.io und arbeite seit über 10 Jahren mit PDFs
      Wie Webbrowser müssen PDF-Viewer eine enorme Vielfalt an PDFs akzeptieren
      Weil PDFs so alt sind, nehmen Dateierzeuger willkürliche Änderungen vor, solange es in dem Viewer, den sie benutzen, gut aussieht
      Deshalb hat unser Unternehmen ein SDK für AI document processing entwickelt (REST API, PDF als Eingabe, strukturierte Daten als JSON zurück)
      Durch Erfahrung mit visuellen Verfahren ebenso wie mit struktureller Vor- und Nachverarbeitung liefern wir bessere Ergebnisse bei Leistung und Kosten als rein visionsbasierte Ansätze
      Wenn man sich nicht selbst mit PDF-Verarbeitung herumschlagen und sich lieber auf das eigentliche Geschäft konzentrieren will, kann das hilfreich sein
      https://www.nutrient.io/sdk/ai-document-processing

    • Wenn schon jemand mit Expertenwissen zur internen PDF-Struktur da ist, habe ich eine Frage
      Warum ist mupdf-gl (auf einem typischen Desktop-Linux-System) so viel schneller als praktisch alle anderen Programme?
      Beim Durchsuchen großer PDFs ist es deutlich überlegen, und ich habe mich immer gefragt, warum andere Viewer nicht genauso schnell sein können
      Falls jemand dazu Einsichten hat, würde ich sie gern hören

    • Im Ergebnis hat man die Parsing-Arbeit einfach an die Software ausgelagert, die das PDF beim Rendern in ein Bild umwandelt

  • Ich denke schon lange, dass wir uns von layoutzentrierter Dokumentkommunikation lösen sollten
    Anders gesagt: Professionell gestaltetes Layout ist eigentlich eher eine alte Gewohnheit und hat fast nichts mit dem tatsächlichen Verständnis des Inhalts zu tun
    Zum Beispiel sind Unterlagen für Einreichungen bei Regulierungsbehörden oft extrem umfangreich, und um alle Layout-Regeln einzuhalten, verbringt man in Microsoft Word sehr viel Zeit
    Um dieses Layout zu garantieren, reicht man dann im DOCX- oder PDF-Format ein, aber diese Formate sind für Programme sehr ungeeignet, um Inhalte automatisch zu extrahieren oder weiterzuverarbeiten
    LLMs können solche Dateien zwar lesen, aber im Vergleich zu einfachen maschinenfreundlichen Dateien wie Text, markdown, XML oder JSON kostet das deutlich mehr Rechenaufwand

    Als Alternative denke ich über die Möglichkeit nach, einfache Formate nach dem Prinzip „machine first“ und „content first“ zu standardisieren, etwa auf Basis von JSON, XML oder HTML
    Sie würden nur minimale Struktur- und Bild-Einbettungsinformationen enthalten, und für Menschen könnte eine Viewer-App sie ansprechend rekonstruieren
    Die maschinelle Verarbeitung wäre deutlich einfacher
    Obwohl es mit HTML/Browsern, EPUB und Ähnlichem bereits verwandte Formate gibt, scheint es Zeit, den klassischen Ansatz zu ersetzen
    Ich hoffe, dass die LLM-Revolution in diese Richtung führt und dass teures PDF-Parsing künftig nur noch in Legacy-Pipelines übrig bleibt

    • Ich stimme den Problemen mit PDF zu, würde aber zurückfragen, ob DOCX wirklich so schlimm ist
      Ich habe noch nie selbst einen DOCX-Parser gebaut, aber DOCX basiert auf XML, und solange man nicht explizit Layout vorgibt, ist nicht alles in absolute Koordinaten gegossen; wenn JPEG 0 Punkte, PDF 15 Punkte und markdown 100 Punkte sind, dann wäre DOCX vielleicht ein Schwierigkeitsgrad von ungefähr 80
  • Ich fand das eine großartige Zusammenfassung, und es gab noch einen zusätzlichen Punkt, den ich interessant fand
    Incremental-save-Ketten: Der erste startxref-Offset ist meist okay, aber die /Prev-Links, die Acrobat bei wiederholten Änderungen immer weiter anhängt, zeigen oft ein paar Bytes vor das nächste xref
    Die meisten Viewer (PDF.js, MuPDF, sogar Adobe Reader) suchen dann stumpf im ganzen Dateiinhalt nach dem obj-Token und rekonstruieren daraus neue Tabellen, während spezifikationsnahe Parser explodieren
    Wenn man in der Praxis Dokumente verarbeiten will, die von mehreren Anwendungen wiederholt verändert wurden, ist so ein Recovery- bzw. Salvage-Pfad unverzichtbar

    • Guter Punkt, das war in meinem Beispieldatensatz ein häufiger Fehlerfall
      Oft zeigt eine frühere Referenz oder ein Element in der Kette auf einen Offset außerhalb der Datei, auf Offset 0 oder auf einen sonstigen falschen Wert
      Dieser Artikel wurde durch meine Überarbeitung der frühen Parsing-Logik in meinem Projekt PdfPig ausgelöst
      Anfangs hatte ich den Code aus Java PDFBox portiert, aber ich wollte ihn schneller und einfacher machen
      Die neue Logik scannt die gesamte Datei, sobald auch nur eine xref-Tabelle oder ein xref-Stream fehlt, und vertraut im Recovery-Pfad nur diesem Offset
      Allerdings ist sie definitiv langsamer als vorher, und ich bin mir nicht sicher, ob die Änderung in der Praxis wirklich gut ist
      Ich untersuche gerade verschiedene Sonderfälle in einem Testsatz mit 10.000 Dateien
      https://github.com/UglyToad/PdfPig/pull/1102
  • Mit funktionierenden Annahmen und einem geeigneten PDF-Objektparser wirkt es vielleicht einfach, aber ich glaube, in Wirklichkeit ist es das ganz und gar nicht
    Diese Situation ist wie die Hölle der PDFs
    PDF ist keine Spezifikation, sondern ein sozialer Konsens, eher eine „Vibe“-Sache
    Je mehr man sich dagegen wehrt, desto tiefer sinkt man hinein, und inzwischen fühlt es sich an, als würden wir alle in einem Sumpf leben, der sich dem Blick Gottes entzieht
    Darüber musste ich lachen

    • Der Witz ist, dass sich dieser Text anhört, als hätte James Mickens ihn geschrieben
  • Auf die Frage „Willst du PDFs parsen?“ kann ich mit Nachdruck sagen: auf keinen Fall
    Warum, wird im Originalbeitrag gut erklärt

    • Ich wünschte, meine Bank würde die Unterlagen in einem besser lesbaren Format bereitstellen, aber bis dahin habe ich wohl keine Wahl

    • Ich habe diesen Fehler schon einmal gemacht und werde ihn nie wieder machen

  • Als jemand, der schon einen PDF-Parser geschrieben hat, finde ich PDF ein wirklich seltsames Format
    Ich glaube, diese Merkwürdigkeit kommt aus dem ursprünglichen Design als Mischung aus Binär- und Textformat
    Selbst die etwas schlampig ungenauen xref-Offsets stammen vermutlich von Bugs bei der Verarbeitung von LF/CR-Zeilenumbruchkonvertierungen
    Einer der Punkte, die im Artikel nicht erwähnt wurden, ist, dass moderne PDFs (v1.5+) oft keinen normalen Text-xref-Table mehr haben, sondern einen „xref stream“
    Ab v1.6 können sogar die Objekte selbst in einem object stream liegen

    • Ich war auch überrascht, dass der Text nicht über einfache xref-Tabellen hinaus auf Streams und Kompression einging
      Erst scheint alles unproblematisch, aber dann steckt das gewünschte Objekt in einem Stream, dieser Stream verwendet eine abgewandelte PNG-Kompression, oder der Offset liegt in einem flate-komprimierten xref stream, und schon wird es unerquicklich
      Dazu kommen mehrere vermischte Dokumentversionen, sodass es komplex wird zu bestimmen, was überhaupt der neueste Stand ist
      Das PDF-1.7-Dokument ist leicht zu bekommen, aber bis vor gerade einmal zwei Jahren war die PDF-2.0-Spezifikation noch hinter einer Paywall versteckt
  • PDF ist kein Format, das für Streaming entworfen wurde
    Durch das trailer dictionary am Ende wird es schwierig, die Datei zu parsen, bevor sie komplett geladen ist
    Allerdings gibt es auch „streamingfähige PDFs“, bei denen die erste Seite sofort gerendert werden kann, wenn die nötigen Informationen am Anfang liegen, auch wenn das nicht für den Rest gelten muss
    Es ist allerdings schon etwas her, seit ich mich zuletzt intensiv mit PDFs beschäftigt habe

    • Auch mit einem Footer kann PDF gestreamt werden, solange die Website Range Requests unterstützt und den Content-Length-Header korrekt setzt
      Ein Streaming-Reader kann einen HEAD-Request senden, dann die letzten paar hundert Bytes der Datei anfordern, um Pointer und Tabellen zu finden, und anschließend den Rest nachladen
      Für in Echtzeit erzeugte PDFs ist das ungeeignet, aber bei einem normalen älteren Webserver reichen ein bis zwei zusätzliche Roundtrips völlig aus
      Leider kümmern sich nur wenige um Range-basierte Parser pro Datei, aber technisch unmöglich ist es nicht

    • Genau, es gibt das Format Linearized PDF, das genau dafür entwickelt wurde, die erste Seite schnell anzuzeigen, ohne die ganze Datei herunterzuladen
      In der Zusammenfassung habe ich es weggelassen, weil dazu noch viel Zusatzbeschreibung nötig gewesen wäre

  • Eines meiner ersten Projekte, nachdem ich Python gelernt hatte, war ein PDF-Parser
    Ich wollte damit automatisch Karten für eine DnD-Kampagne extrahieren, aber das Ergebnis war ein Fehlschlag, haha

  • Ich habe schon einmal einen TIFF-Reader geschrieben
    TIFF ist ebenfalls berüchtigt dafür, leicht zu schreiben, aber schwer zu lesen zu sein
    PDF scheint in dieselbe Kategorie zu fallen