Apache Tika im Test: Es liest die Bytes, nicht den Dateinamen – bis Markdown ins Spiel kommt

Zuletzt aktualisiert am August 14, 2026
Apache Tika im Test: Es liest die Bytes, nicht den Dateinamen – bis Markdown ins Spiel kommt
KI-Zusammenfassung
Apache Tika ist das Dokumenten-Parsing-Toolkit der Apache Software Foundation: Gib ihm eine Datei fast beliebigen Formats, und es gibt dir reinen Text plus ein normalisiertes Metadaten-Dictionary zurück. Im Projekt-README ist von mehr als tausend unterstützten Dateitypen die Rede, und Tika erreicht das, indem es die spezialisierten Bibliotheken direkt mitbringt — PDFBox für PDFs, Apache POI für Office-Dokumente, jsoup für HTML, einen ODF-Reader für ODT — sodass das Ganze als einzelnes, großes Jar ausgeliefert wird und zur Parse-Zeit nichts nachgeladen werden muss. In einer Datenpipeline ist Tika die unscheinbare erste Stufe: die Komponente vor einem Suchindex, einem eDiscovery-Prüfset oder einem LLM-Korpus, die einen heterogenen Datei-Haufen in etwas Einheitliches verwandelt.

Apache Tika ist das Dokumenten-Parsing-Toolkit der Apache Software Foundation: Gib ihm eine Datei in fast beliebigem Format, und du bekommst reinen Text plus ein normalisiertes Metadaten-Dictionary zurück. Im Projekt-README ist von mehr als tausend unterstützten Dateitypen die Rede, und Tika erreicht das, indem es die spezialisierten Bibliotheken direkt mitbringt — PDFBox für PDFs, Apache POI für Office-Dokumente, jsoup für HTML, einen ODF-Reader für ODT — sodass das Ganze als einzelnes, großes Jar ausgeliefert wird und zur Parse-Zeit nichts nachgeladen werden muss. In einer Datenpipeline ist Tika die unscheinbare erste Stufe: die Komponente vor einem Suchindex, einem eDiscovery-Prüfset oder einem LLM-Korpus, die einen wilden Mix aus Dateien in etwas Einheitliches verwandelt. Im Kern erfüllt sie zwei Aufgaben: herauszufinden, was ein Byte-Stream ist, und anschließend Text sowie Metadaten daraus zu extrahieren.

Es ist das unkomplizierteste Tool, das ich seit Langem eingerichtet habe. Ein Jar, java -jar tika-app-3.3.2.jar --text file.pdf, keine Config-Datei, keine Model-Gewichte, kein Nachinstallationsschritt — und es lief sauber auf einem brandaktuellen JDK, das am selben Nachmittag andere Java-Tools auf demselben Host direkt ausgebremst hat. Die Katalogbehauptung wollte ich allerdings nicht einfach so stehen lassen; die überprüfbare Frage ist enger gefasst: Was macht Tika wirklich, wenn die Eingabe lügt? Also habe ich ein kontrolliertes Testset gebaut, in dem jeder Inhaltsblock einen eindeutigen Marker-Token trägt, dasselbe logische Dokument in neun Containerformate gerendert und dann alles mit falschen Endungen, fehlenden Endungen, ganz ohne Dateinamen, Null-Byte-Dateien und halb geschriebenen Binärdateien angegriffen.

Die eigentliche spannende Beobachtung steckt in der Erkennung. Ich habe eine PDF in .txt umbenannt und Tika gefragt, was das sei; die Antwort lautete application/pdf. Dann habe ich den Dateinamen komplett entfernt, die Rohbytes per stdin eingespeist und dieselbe Antwort erhalten. Über die fünf inhalts-erkennbaren Formate in meinem Set hinweg galt das in allen 20 eindeutigen logischen Bedingungen: drei Dateiname-Varianten plus je eine Variante ohne Dateiname pro Format. Das Testgerüst führte den Stream-Fall dreimal mit unterschiedlichen Labels aus und erzeugte damit 30 erfolgreiche Rohdurchläufe, aber diese Wiederholungen liefern keine unabhängigen Belege. PDF und RTF enthalten erkennbare Bytes; DOCX verrät sich über den Container; HTML und XML lassen sich an Markup oder Root-Content identifizieren. Unterschiedliche Mechanismen, gleich brauchbares Ergebnis in diesem Testset: Die Endung konnte den Inhalt nicht ausstechen. Bei Markdown sieht es anders aus: In der Text-Familie fällt es in text/plain zurück, sobald der Dateiname falsch ist oder fehlt. Seine Identität hing hier komplett an .md.

Für alle Zahlen im Folgenden gelten zwei Grenzen. Ich habe Apache Tika 3.3.2 getestet — und am 27. Juli 2026 geprüft, dass dies noch die neueste stabile Version war; die 4.0.0-Reihe existiert auf Maven Central nur als Alpha- und Beta-Builds. Das Projekt lag am 27. Juli 2026 bei ungefähr 3,9k GitHub-Sternen und steht unter Apache-2.0, also so wenig kommerziell belastend wie eine Lizenz nur sein kann. Und OCR habe ich überhaupt nicht getestet. Keine einzige gescannte Seite, keine PDF nur mit Bildern. Tesseract und poppler sind auf dem Rechner, auf dem ich das ausgeführt habe, nicht installiert, daher waren alle OCR-Pfade schon dicht, bevor sie überhaupt starten konnten. Hier gibt es keine OCR-Zahlen, weil es schlicht keine OCR-Zahlen gibt.

Was Tika ist, wenn man die Marketing-Sprache von der Verpackung abzieht

Die gängige Annahme lautet, Apache Tika sei ein Dokumentenkonverter — DOCX rein, sauberes Markdown mit Überschriften und Tabellen raus. Das ist es nicht, und je früher das klar ist, desto besser lässt sich das Tool einordnen.

Der hier getestete Weg hat drei relevante Stufen: einen Content-Type-Detektor, einen Dispatcher, der die Bytes an den passenden Parser weiterreicht, und den --text-Ausgabehandler der CLI, der flachen Text zusammen mit separat abrufbaren Metadaten ausgibt. In diesem Ausgabeversprechen gibt es keine Title-Objekte, kein ListItem und keinen rekonstruierten Tabellenraster. Tika bietet außerdem weitere Handler und APIs, einschließlich XHTML-/SAX-orientierter Ausgabe; die habe ich nicht getestet. Jede Aussage zur Struktur unten bezieht sich daher auf tika-app --text und nicht darauf, dass das Toolkit nirgends einen strukturierten Event-Stream hätte.

Das klingt nach einer Einschränkung, und in einer Hinsicht ist es das auch. Es bedeutet aber ebenfalls, dass Tika nichts falsch klassifizieren kann — und genau diesen Tausch machen seine lauteren Cousins in die andere Richtung.

Die Erkennung selbst läuft in einer dokumentierten Reihenfolge ab: zuerst Signatur-Bytes, dann die Prüfung auf XML-Root, dann der Dateiname per Glob, dann ein von dir selbst mitgegebener Typ (Tikas eigene Doku zur Erkennung beschreibt das so). Erst wenn der Typ aufgelöst ist, gibt der Dispatcher die Bytes an den passenden eingebetteten Parser weiter — PDFBox, POI, jsoup, TextAndCSVParser für die Text-Familie.

Diese Trennung von Erkennung und Parsing ist kein internes Detail ohne Bedeutung. Sie erklärt, warum eine Datei, die zu kaputt zum Parsen ist, trotzdem korrekt typisiert werden kann — und genau darin liegt der praktischste Trick, den Tika bietet, sobald Dinge anfangen, kaputtzugehen.

Setup: ein Jar, ein Befehl und ein JVM, das nicht zickt

Die Installation besteht aus einem Download. tika-app-3.3.2.jar von Maven Central ist rund 67 MB groß — ein Fat Jar, das jeden Parser bündelt — und danach heißt es einfach java -jar tika-app-3.3.2.jar --text file.pdf. Keine Config-Datei, keine Model-Gewichte, kein Nachinstallationsschritt, keine brew install-Kette.

Die JDK-Seite hat mich überrascht. Ich habe das Ganze auf OpenJDK 26.0.1, also einem frischen Nicht-LTS-Build, laufen lassen, und --version, --text, --metadata und --detect lieferten alle Exit 0 ohne Kompatibilitätsbeschwerden. Das ist erwähnenswert, weil ich am selben Tag auf demselben Host Apache Nutch getestet habe und sein Crawl-Zyklus unter JDK 26 überhaupt nicht lief — wegen der Entfernung des SecurityManagers in neueren JDKs braucht es dort ein LTS 21 oder darunter. Tika war das egal. Wenn du JVM-Tools wegen genau dieser Art Ärger bisher gemieden hast, ist Tika nicht die Stelle, an der es weh tut.

Zwei ehrliche Abzüge zur Einrichtung: Die CLI startet pro Aufruf eine frische JVM, also ist Cold Start real — 131 Aufrufe für mein Harness brauchten ungefähr eine Minute, die größtenteils für JVM-Aufwärmen draufging. Wenn du Dateien in größerem Volumen verarbeiten willst, nimm die Library oder den Server-Modus, nicht eine Shell-Schleife um das Jar. Und die „ohne Abhängigkeiten“-Geschichte hat eine harte Grenze: PDF-Textlayer-Extraktion braucht nichts Externes, aber OCR braucht Tesseract und poppler. PDFs mit Textlayer, DOCX, ODT, RTF, HTML, XML, TXT, Markdown und CSV wurden auf einem Host ohne diese Tools problemlos verarbeitet. Gescannte Dokumente wären das nicht gewesen, und ich tue nicht so, als hätte ich etwas anderes getestet.

Der Kontrast zum Schwesterpaket, das ich am selben Tag getestet habe, unstructured, ist ziemlich deutlich: Der Weg für elektronische PDFs war dort komplett blockiert, weil schon der Import des PDF-Moduls den Inferenz-Stack (torch und Verwandte) beim Laden zieht — also noch vor der Strategie-Weiterleitung, sodass selbst die „fast“-Strategie ohne diese Abhängigkeiten gar nicht importiert. Tika hat denselben PDF-Textlayer mit einem simplen java -jar verarbeitet.

Der Test mit den lügenden Endungen: MIME-Typ-Erkennung ignoriert den Dateinamen

Measured results chart: Type detection across filename conditions

Acht Formate, jeweils mit korrekter Endung, absichtlich falscher Endung oder ganz ohne Endung sowie als dateinamenloser Byte-Stream auf stdin. Das sind 32 eindeutige logische Bedingungen. Das ursprüngliche Testgerüst führte dieselben Stream-Bytes außerdem einmal unter jedem Dateinamen-Label aus, was 48 Rohdurchläufe ergibt; diese drei Stream-Zeilen fallen aber zu einer einzigen Bedingung zusammen, weil stdin keinen Dateinamen mitliefert.

FixtureWahrer TypUmbenannt zuRichtige EndungLügnerische EndungKeine EndungRoh-Stream, kein Dateiname
PDFapplication/pdf.txt
DOCXOOXML wordprocessingml.jpg
RTFapplication/rtf.html
HTMLtext/html.csv
XMLapplication/xml.txt
Plain texttext/plain.pdf
Markdowntext/markdown.pdftext/plaintext/plaintext/plain
CSVtext/csv.txttext/plaintext/plaintext/plain

(Die Stream-Spalte fasst alle drei Endungsbedingungen zusammen, weil es ohne Dateinamen nichts gibt, was der Glob lesen könnte.)

Die fünf inhalts-erkennbaren Formate — PDF, DOCX, RTF, HTML und XML — trafen den echten Typ in 20 von 20 eindeutigen Bedingungen (und 30 von 30 Rohdurchläufen inklusive doppelter Stream-Tests). Eine PDF mit Namen report.txt blieb eine PDF. Eine DOCX mit Namen photo.jpg blieb eine DOCX. Dafür brauchte es keinen Dateinamen. Das heißt nicht, dass alle fünf ausschließlich feste Byte-Signaturen nutzen: PDF und RTF haben erkennbare Header, DOCX ist ein ZIP-basierter Container, und HTML/XML werden über Markup oder Root-Content identifiziert. In diesen Fixtures konnte die lügnerische Endung nicht gewinnen.

Dann das Regime der Text-Familie. Markdown wurde nur dann als text/markdown erkannt, wenn die .md-Endung vorhanden und lesbar war. Umbenennen, die Endung entfernen oder es als Stream schicken — und in diesem Test fiel es auf text/plain zurück. CSV verhielt sich auf diesem bewusst kleinen Raster genauso: text/csv kam nur über den .csv-Glob. Zählt man die eindeutigen Bedingungen, wurde Markdown wie auch CSV jeweils in einer von vier Bedingungen als spezieller Typ erkannt; reiner Text war ohnehin schon text/plain, also gab es für ihn nichts, worauf er hätte „zusammenfallen“ können. Die 48 Rohdurchläufe bleiben als Reproduzierbarkeitsnachweis nützlich, aber nicht als größerer Nenner.

Ein Detail spricht hier für Tika: Die lügnerische Endung gewinnt ebenfalls nicht. Mein Markdown-Fixture, umbenannt in .pdf, kam als text/plain zurück und nicht als application/pdf. Tika glaubte die Lüge nicht; es konnte nur die Wahrheit nicht bestätigen. Auf den übergeordneten Typ zurückzufallen ist ein deutlich besserer Fehler als selbstbewusst den falschen Typ zu behaupten, und dass text/markdown ein dokumentierter Untertyp von text/plain ist, macht diesen Fallback fundiert statt willkürlich.

Bei CSV gibt es einen Vorbehalt. Tika hat einen statistischen CSV-Detektor, und zur Parse-Zeit — bestätigt dadurch, dass TextAndCSVParser in der X-TIKA:Parsed-By-Kette auftauchte — wurde mein kleines 2-Spalten-3-Zeilen-Raster als text/plain statt als text/csv aufgelöst. Das ist eine Einzelbeobachtung an einem bewusst minimalen Fixture. Ein größeres oder gequotetes CSV kann den Detektor durchaus auslösen. Ich behaupte nicht, dass die Inhalts-Erkennung von CSV kaputt ist; ich behaupte, dass auf diesem Raster die Endung dafür sorgte, dass text/csv entstand.

Warum das in einer echten Upload-Pipeline wichtig ist

Das konkrete Szenario ist ein Upload-Router. Nehmen wir an, du nimmst Nutzer-Uploads an und leitest sie nach Typ weiter: PDFs an den Rechnungsparser, Tabellenkalkulationen an den Ledger-Importer, alles andere an einen Textindex. Wenn du der Endung vertraust, landet jemand, der eine PDF mit dem Namen notes.txt hochlädt, im falschen Zweig — und das ist noch die harmlose Variante; die bösartige ist eine Polyglot-Datei mit freundlicher Endung.

Bei den hier getesteten binären und Markup-Fixtures hat Tika anhand des Inhalts geroutet, selbst nachdem der Dateiname verschwunden war. Das ist nützlich, wenn ein Blob-Store oder HTTP-Body-Handler den Namen entfernt hat. Dieses Ergebnis sagt nichts über Tikas lange Randfälle, mehrdeutige Dateien oder Polyglots aus. Die getesteten Text-Familien-Fixtures verhielten sich anders: Wenn die Pipeline die Dateinamen entfernte, kamen Markdown und CSV als text/plain an, sodass Regeln, die auf ihre spezifischen Medien-Typen zielen, nicht mehr griffen. Bewahre den ursprünglichen Dateinamen als Sidecar-Metadatum auf, statt zu erwarten, dass die Inhalts-Erkennung ihn rekonstruiert.

Der eingepflanzte Inhalt blieb erhalten. --text bügelte die Struktur glatt.

Treue ist die zweite Achse, und sie teilt sich sauber in zwei Teile. Ich habe ein kanonisches Dokument (Überschriften, zwei Fließtext-Absätze, eine Aufzählung, eine nummerierte Liste, einen Schlussabsatz) in HTML, Markdown, Plain Text, DOCX, PDF, RTF, ODT und XML gerendert sowie ein Tabellendokument in HTML, Markdown, Text, DOCX, CSV und XML. Vierzehn Carrier-Renderings. Jeder Block trägt einen eindeutigen Token — zztitle1, zzitem3, zztblcell_beta und so weiter — sodass „überlebt“ versus „verloren“ ein exakter Substring-Test ist und keine Ermessensfrage.

Der Recall der Marker-Tokens lag in allen vierzehn Renderings bei 1.000. Kein einziger eingepflanzter Token ging verloren: Jede markierte Tabellenzelle, jedes Listenelement und jede Überschrift war vorhanden. Drei lokale Wiederholungen pro Carrier nach dem Warm-up lieferten byte-identische --text-Ausgaben zurück. Dieses Kriterium sagt nichts über unmarkierte Zeichen, Reihenfolge, Leerzeichen, Unicode-Normalisierung, wiederholten Inhalt, Links, Header, Fußnoten oder eingebettete Objekte. Es ist ein Block-Vorhandenseins-Check, kein Beweis für vollständige Dokumenttreue.

Die flache Textausgabe gibt den Großteil der Ausgangsstruktur auf.

So sieht das HTML-Tabellendokument aus --text aus:

	Tool	Throughput

	zztblcell_alpha	120

	zztblcell_beta	95

Zeilen mit Tabulatoren getrennt. Die Kopfzeile ist nicht als Kopfzeile markiert. Kein Raster, keine Zellgrenzen außer einem Tab, keine Möglichkeit zu erkennen, dass das jemals eine <table> war. Die DOCX-Tabelle wird auf dieselbe Weise geglättet.

Listen sind subtiler und hängen davon ab, was die Quelle tatsächlich enthielt:

Was das Bullet im Original warCarrierWas --text zurückgibt
Ein literales Zeichen — diese Renderings schrieben - tatsächlich als TextPlain Text, Markdown, RTF, ODT, PDFdas - bleibt erhalten, weil Tika die Zeichen einfach durchreicht
Echte Struktur — ein HTML <li>, ein DOCX-List-Bullet-StyleHTML, DOCXder Marker verschwindet komplett und es bleibt nur der Elementtext übrig: in HTML tab-eingerückt, in DOCX eine einfache, schmucklose Zeile

Tika rendert einen Marker nie neu, wenn er ihm nicht als Text vorliegt. Gleicher Inhalt, anderes Aussehen der Ausgabe.

Der Markdown-Fall macht das besonders klar. Gib Tika eine .md-Datei mit einer Pipe-Tabelle, und die Pipes kommen wörtlich zurück — was so aussieht, als würde Struktur erhalten bleiben. Ist es aber nicht. Tika hat es als Text geparst und die Bytes zurückgegeben. Nichts hat diese Tabelle verstanden.

Das gemessene Versprechen ist also enger: Alle eingepflanzten Marker überlebten, während --text weder typisierte Elemente noch ein rekonstruierbares Tabellenraster beibehielt. Das als Parser-Defekt zu bezeichnen, würde den Punkt verfehlen. Die flache Extraktion vermeidet absichtlich das Problem der Elementklassifikation; sie kann aber auch keinen Downstream-Consumer zufriedenstellen, der genau diese Elementtypen braucht. Wenn du typisierte Blöcke oder rekonstruierte Tabellen willst, ist --text nur eine Komponente des Stacks, nicht der ganze Stack. Andere Tika-Handler können mehr Struktur liefern, aber die waren außerhalb dieses Laufs.

Der Standardvorbehalt für jede Fidelity-Zahl hier: Sie stammen aus kontrollierten synthetischen Fixtures auf einem Rechner, in einer Version, mit einem JDK. Sie zeigen, dass die markierten Blöcke in der Ausgabe vorhanden waren. Sie belegen weder Zeichen-für-Zeichen-Erhalt noch Genauigkeit in einem chaotischen realen Korpus.

Metadaten: normalisiert und angenehm unwillig zu erfinden

Measured results chart: Metadata recovery by carrier

Ich habe bekannte Werte für Autor, Titel und Erstellungsdatum in jeden Carrier eingebettet, der eine Metadaten-Schicht besitzt, und dann geprüft, was zurückkam.

Carrierauthor → dc:creatortitle → dc:titlecreated → dcterms:created
HTML (<meta name=author>, <title>)nicht eingebettet
DOCX (Core Properties)✅ exakt 2021-03-15T09:30:00Z
PDF (Info-Dict)vorhanden, aber das war der eigene Zeitstempel des Generators — nicht gewertet
ODT (meta.xml)✅ exakt 2021-03-15T09:30:00Z
TXT / MD / CSV / RTF / XMLkeine Metadaten-Schicht

Autor und Titel wurden auf 4 von 4 Carriern mit Metadaten wiederhergestellt — und das ist der relevante Punkt — sie sind normalisiert. Ein HTML-<meta name="author">, eine DOCX-Core-Property, ein PDF-/Author-Eintrag und ein ODT-dc:creator-Element landen alle unter demselben dc:creator-Schlüssel. Du schreibst also einen Consumer, nicht vier.

created ist die ehrliche Schwankung. DOCX und ODT gaben meinen exakt eingebetteten Zeitstempel aus 2021 zurück. Das PDF lieferte ein Erstellungsdatum, aber es war das Datum, das die Generator-Bibliothek beim Build gesetzt hatte — nicht der Wert, den ich einbetten wollte — deshalb werte ich es als vorhanden, nicht als wiederhergestellt. Und die Formate ohne Metadaten-Schicht lieferten gar nichts, was die richtige Antwort ist. Tika rät keinen Autor aus dem Textkörper zusammen.

Absichtlich kaputt gemacht, und die daraus entstehende Triage-Idee

Vier feindliche Eingaben. Eine Null-Byte-Datei. Ein gültiger PDF-Header mit abgeschnittenem Inhalt. Ein gekürztes DOCX-ZIP. Und eine UTF-8-Datei mit Mehrbyte-Zeichen ohne BOM und ohne Encoding-Deklaration. Das sind lokale Fixture-Formen, keine Tika-Grenzfälle.

Das zugrunde liegende Testgerüst, die generierten Fixtures, die Roh-JSON, die Jar-Prüfsumme und das Umgebungs-Manifest sind in diesem Entwurf nicht verlinkt. Ein externer Leser kann die exakten Nenner daher noch nicht unabhängig reproduzieren. Betrachte die Tabellen als berichtete Beobachtungen; eine Veröffentlichung sollte ein stabiles Bundle mitliefern, bevor diese Zahlen als Fremdbeleg verwendet werden.

Eingabe--text / --jsonFehlermeldung--detect
0-Byte-DateiExit 1, leere StdoutZeroByteFileException: InputStream must have > 0 bytesExit 0 → text/plain mit Dateiname, application/octet-stream aus Stream
Abgeschnittene PDFExit 1, leere StdoutTikaException: TIKA-198: Illegal IOException from PDFParserExit 0 → application/pdf
Abgeschnittene DOCXExit 1, leere StdoutPOI FATAL: "XML document structures must start and end within the same entity"Exit 0 → OOXML-Typ
UTF-8, kein BOM, keine DeklarationExit 0nichtsExit 0 → text/plain, Charset UTF-8

Extraktion scheitert laut statt leise, und diese Fehler haben alle dieselbe äußere Form. Die Null-Byte-Datei, die abgeschnittene PDF und die gekürzte DOCX erzeugten jeweils eine Exception, Exit 1 und leere Stdout. Die CLI verschluckt den Fehler nicht zu einem hübsch leeren Ergebnis. Prozesssicher sind diese Fälle — kein Hängenbleiben, kein Segfault — aber der Aufrufer muss Exit-Status und Stderr prüfen und darf sich nicht nur auf einen leeren String verlassen.

Erkennung und Parsing sind entkoppelt. Bei beiden abgeschnittenen Binärdateien gab --detect Exit 0 mit dem erwarteten Typ aus dem intakten vorderen Inhalt zurück; der Parser scheiterte dann am beschädigten Rest. Eine Pipeline kann Erkennung also als separates Triage-Signal vor oder nach einem fehlgeschlagenen Parse verwenden. Ob Detect-first als Standard sinnvoll ist, hängt vom Deployment-Modus ab: Dieser Test hat Detect-first nicht gegen Parse-only benchmarked, und zwei frische CLI-JVMs sind bei hohem Volumen vielleicht der falsche Kompromiss.

Charset-Erkennung funktioniert. Die Datei ohne BOM und ohne Deklaration wurde als UTF-8 dekodiert, und 日本語テスト kam intakt durch. Eine kleine Einschränkung für alle, die auf die Metadaten-Dictionaries schauen: Meine reinen ASCII-Fixtures melden charset=ISO-8859-1, was auf ASCII-Bytes nicht von UTF-8 zu unterscheiden ist. Das ist kein Fehler, sondern ein Gleichstand.

Tika neben unstructured: gleiche Dateitypen, andere Aufgabe

Beide wurden in derselben Research-Session getestet, aber hier geht es um eine Taxonomie von Ausgabeversprechen, nicht um einen symmetrischen Benchmark. Die Tools wurden an unterschiedlichen Ergebnissen gemessen.

Verwandte Rezension: Unstructured Review.

Apache Tikaunstructured
Woran ich es gemessen habeContent-Treue: Ging irgendetwas verloren?Elementklassifikations-Treue: Bekam jeder Block den richtigen Typ?
ErgebnisAlle eingepflanzten Marker waren in allen vierzehn Renderings vorhandenIm separaten Klassifikationstest hatte eine einfache Texttabelle einen Table-Recall von 0.000, und eine Überschrift mit Verb wurde als narrativer Text eingestuft
Zurückgegebene typisierte Elementekeine — es kam überhaupt keine Struktur zurückTitle, NarrativeText, ListItem, Table — genau das, was Tika bewusst nicht liefert
OCRAuf meinem Host blockiert, weil Tesseract fehltAuf meinem Host blockiert, weil Tesseract fehlt

Flache, Marker-erhaltende Ausgabe gegen typisierte Elemente mit beobachteten Klassifikationsfehlern. Wähle nach dem, was der Downstream-Consumer braucht. Wenn es ein Suchindex oder ein LLM-Kontextfenster ist, reicht flacher Text womöglich aus. Wenn es auf Elementtypen basiert, kann Tikas --text diesen Vertrag nicht erfüllen.

Wir beide haben keine Zahlen zu gescannten Dokumenten.

Vorteile und Nachteile

Vorteile

  • Die Content-Type-Erkennung ignorierte lügende Dateinamen in 20/20 eindeutigen Bedingungen über die fünf inhalts-erkennbaren Fixtures hinweg; auch die doppelten Stream-Durchläufe stimmten überein.
  • Jeder eingepflanzte Marker überlebte in allen 14 Carrier-Renderings, einschließlich markierter Tabellenzellen und Listenelemente.
  • Drei lokale Wiederholungen waren reproduzierbar: Jeder Carrier lieferte in dieser Umgebung byte-identischen Text zurück.
  • Metadaten wurden über Formate hinweg normalisiert — dc:creator / dc:title / dcterms:created, unabhängig vom Quellformat, und auf 4/4 metadatenführenden Carriern wiederhergestellt.
  • Für die getesteten Formate tatsächlich ohne Zusatzabhängigkeiten: PDF-Textlayer, DOCX, ODT, RTF und HTML parsen aus einem einzigen Jar ohne externe Binärdateien.
  • Läuft sauber auf OpenJDK 26 — keine Beschränkung auf LTS-Versionen.
  • Die Erkennung bleibt auch bei abgeschnittenen Binärdateien korrekt (Exit 0) und liefert damit ein verlässliches Triage-Signal, wenn das Parsing fehlschlägt.
  • Apache-2.0, ausgereift, aktiv gepflegt.

Nachteile

  • Markdown- und CSV-Identität hängen vollständig von der Dateiendung ab; 10 von 18 signaturlosen Zellen fielen auf text/plain zurück, sobald der Dateiname fehlte oder falsch war.
  • --text gibt keine Elementtypen zurück; Tabellenraster wurden zu tab-getrennten Zeilen geglättet, strukturelle Listenmarker gingen verloren.
  • Die Extraktion wirft bei leeren und korrupten Eingaben ungefangene Fehler; beide Fälle sehen aus Sicht des Extraktionsaufrufs gleich aus.
  • 67-MB-Jar plus eine JVM-Kaltstartphase pro Aufruf im CLI-Modus.
  • OCR und gescannte Bild-PDFs wurden hier überhaupt nicht getestet — Tesseract und poppler fehlten, daher wird über diesen Pfad keinerlei Aussage gemacht.
  • Jede Zahl hier basiert auf synthetischer Ground Truth auf einem Rechner, in einer Version. Genauigkeit im echten Korpus, verschlüsselte Dateien, eingebettete/rekursive Dokumente und Durchsatz im großen Maßstab wurden nicht gemessen.

Für wen es passt — und für wen nicht

Tika passt, wenn deine Eingabe Dateien sind, die du bereits besitzt, und deine Ausgabe Text plus Metadaten für maschinelle Auswertung sein soll. Suchindizierung, eDiscovery, Archivverarbeitung, das Befüllen eines LLM-Korpus, die Content-Type-Validierung in einer Upload-Pipeline. Es ist als erste Triage- und Normalisierungsstufe vor etwas Intelligenterem nützlich: die getesteten Typen erkennen, flachen Text extrahieren und das Ganze mit expliziten Prüfungen für Inhalte weiterreichen, die deine Pipeline nicht verlieren darf.

Lass es weg — oder genauer: hör nicht bei --text auf — wenn du typisierte Elemente, rekonstruierte Tabellen oder Dokumentlayout brauchst. Lass es weg, wenn deine Dokumente Scans sind, zumindest bis du Tesseract installiert und eigene Zahlen erhoben hast, denn ich habe keine. Für Arbeit in großem Umfang solltest du die Library oder den Server-Modus gegen die CLI mit repräsentativen Dokumenten benchmarken. Der Prozessstart war in diesem kleinen-Dateien-Test sichtbar, aber Durchsatz und Ressourcenverbrauch wurden nicht gemessen.

Der Punkt, der viele überrascht: Wenn deine Speicherschicht Dateinamen entfernt und du Markdown oder CSV verarbeitest, verlass dich nicht darauf, dass Tika diese von Plain Text unterscheidet. Behalte den Originalnamen.

Alternativen und wo Thunderbit steht

Zuerst eine faire Einordnung, denn der ehrliche Vergleich dreht sich hier um Eingaben, nicht um Qualität. Tika ist ein kostenloses, Apache-2.0-lizenziertes, selbst gehostetes Toolkit zum Parsen von Dateien. Dateien, die du auf der Platte oder in einem Bucket hast. Es holt keine Seiten ab, führt kein JavaScript aus, kämpft nicht gegen Anti-Bot-Schutz und gibt auch nicht vor, das zu tun.

Genau an dieser Grenze kann ein Managed Web-Extraction-Service, einschließlich unseres eigenen Thunderbit, in die Architektur kommen: Er holt Live-Seiten, während Tika Dateien verarbeitet, die du bereits besitzt. Dieser Artikel hat diese Dienste nicht gegen Tika benchmarked, und sie sind kein Ersatz für dieselbe Eingabe.

Die saubere Trennung: Tika für Dokumente, die bereits bei dir liegen; eine Managed-Extraction-API für Webseiten, die du erst holen musst. Viele Pipelines setzen beides ein — auf der Web-Seite crawlen und extrahieren, und Tika für die zurückkommenden PDF- und DOCX-Anhänge.

Wenn du den breiteren Open-Source-Bereich vergleichst, habe ich den vollständigen Vergleich von Open-Source-Scrapern zusammengestellt, einen Überblick über die nützlichsten Scraping-Projekte auf GitHub, eine praxisnahe Crawl4AI-Review zum browsergestützten Markdown-Ansatz und eine breitere Übersicht über Scraping-Tools. Für den No-Code-Weg gibt es außerdem eine Anleitung, wie man eine Website mit AI ausliest.

Thunderbit für die Web-Datenextraktion ausprobieren

Fazit

Sollte man Apache Tika verwenden? Ja, wenn deine Aufgabe darin besteht, heterogene Dateien in flachen Text und normalisierte Metadaten zu verwandeln — und wenn du die Felder oder Marker validierst, die deine eigene Pipeline nicht verlieren darf.

Der stärkste Teil dieses Laufs war der Detektor. Er lieferte in 20 von 20 eindeutigen Bedingungen für die fünf inhalts-erkennbaren Fixtures den erwarteten Typ, inklusive dateinamenloser Streams. Jeder eingepflanzte Marker überlebte über vierzehn Renderings hinweg, und die Ausgabe wiederholte sich in drei lokalen Wiederholungen bytegenau. Nützliche Evidenz. Trotzdem synthetische Evidenz. Dass das hier aus einem einzigen Jar auf diesem JDK lief, ohne externe Binärdateien für die nicht-OCR-Pfade, machte das Deployment angenehm unspektakulär.

Aber man muss die Erwartungen richtig setzen. Jede Tabelle, die du ihm gibst, kommt als tab-getrennte Zeilen zurück. Jeder strukturelle Listenmarker verschwindet. Markdown und CSV verlieren ihre Identität, sobald der Dateiname fehlt. Leere und beschädigte Dateien werfen dieselbe Fehlerform, und um sie auseinanderzuhalten, braucht man den separaten Detect-Aufruf. Und bei OCR, also genau dem Thema, das viele Tika-Nutzer am meisten interessiert, habe ich nichts beizutragen: Ich konnte es nicht ausführen und werde auch nicht raten.

Innerhalb dieser Grenzen erledigt Tika seine unscheinbare Arbeit mit bemerkenswerter Zuverlässigkeit. Es liest die Bytes, nicht das Etikett auf der Verpackung. Frag es nur nicht, in welcher Form die Bytes vorlagen.

Thunderbit für die Web-Datenextraktion ausprobieren Get Started Free

FAQs

Erkennt Apache Tika Dateitypen korrekt, wenn die Endung falsch ist? Für die hier getesteten fünf inhalts-erkennbaren Fixtures: ja. PDF, DOCX, RTF, HTML und XML wurden in allen 20 eindeutigen logischen Bedingungen (30 Rohdurchläufe mit doppelten Stream-Executions) auf ihren erwarteten Medientyp aufgelöst — inklusive irreführender Endungen, ganz ohne Endung und dateinamenloser Streams. Eine als .txt benannte PDF wurde weiterhin als application/pdf erkannt. Markdown und das kleine CSV-Fixture hingen von Dateiname-Informationen ab und fielen auf text/plain zurück, wenn diese fehlten oder falsch waren.

Behält Tika Tabellen und Dokumentstruktur bei? Nicht im hier getesteten --text-Modus. Tabellenraster kamen als tab-getrennte Zeilen zurück, ohne Zellen- oder Kopfzeilen-Semantik, und strukturelle Listenmarker (ein HTML-<li>, ein DOCX-List-Bullet-Style) verschwanden. Jeder eingepflanzte Marker überlebte in allen 14 Carrier-Renderings, aber das beweist keine vollständige Content-Treue, und --text liefert keine Elementtypisierung. Für typisierte Elemente oder rekonstruierte Tabellen solltest du einen anderen Tika-Handler testen oder ein anderes Tool ergänzend einsetzen.

Kann Apache Tika OCR auf gescannten PDFs durchführen? Tika unterstützt OCR über Tesseract, aber ich habe es nicht getestet, und keine dieser Ergebnisse ist eine Aussage darüber. Tesseract und poppler fehlten auf meinem Testsystem, daher waren alle OCR- und Scan-Pfade blockiert, bevor sie liefen. In diesem Test gibt es nirgendwo OCR-Zahlen. Wenn OCR dein Anwendungsfall ist, installiere Tesseract und benchmarke selbst — betrachte diesen Teil von Tika hier als unverifiziert.

Was macht Tika mit leeren oder beschädigten Dateien? Es schlägt laut fehl statt stillschweigend zu scheitern. Eine 0-Byte-Datei wirft ZeroByteFileException; eine abgeschnittene PDF wirft eine TikaException aus PDFParser; eine abgeschnittene DOCX wirft einen POI-XML-Fehler. Alle drei beenden mit Exit 1 und leerer Stdout, also sind leer und beschädigt allein über den Extraktionsaufruf nicht zu unterscheiden. Die Erkennung bleibt jedoch robust — --detect gab bei beiden abgeschnittenen Binärdateien Exit 0 mit dem korrekten Typ zurück, was es zu einem verlässlichen Triage-Schritt macht, bevor du Zeit in einen Parse investierst.

Was wurde in den Tika-Tests nicht abgedeckt? Vier Dinge, ausdrücklich. OCR und Scans (blockiert, nicht getestet). Genauigkeit im echten Korpus — alle Ergebnisse beruhen auf kontrollierten synthetischen Fixtures mit eingepflanzten Marker-Tokens; das misst Treue zu bekannten Labels, nicht Genauigkeit auf schmutzigen Real-World-Dokumenten. Ressourcenverbrauch, Durchsatz und Peak Memory, die ich nicht gemessen habe. Und der lange Schwanz der Behauptung „tausend Dateitypen“: Ich habe neun repräsentative, abhängige-freie Formate getestet, nicht den vollständigen Katalog. Alles hier basiert auf Tika 3.3.2 auf OpenJDK 26.0.1, macOS arm64, auf einem einzelnen Rechner.

Ke
Ke
CTO bei Thunderbit | Senior Data Scientist & ML-Experte Mit fast zehn Jahren Erfahrung in Machine Learning und Data Science ist Ke Shen Absolvent der Columbia University und ehemaliger Senior Data Scientist bei Walmart Labs. Mit tiefgreifender, von Fachkollegen anerkannter Expertise in Python, R, Java und Statistik teilt er praxiserprobte Einblicke dazu, wie sich komplexe KI-Algorithmen von der Theorie in eine produktionsreife Architektur überführen lassen.
Inhaltsverzeichnis
Von der Webseite zur Tabelle
Beschreibe, was du brauchst — Thunderbits KI-Agent erfasst es und exportiert es nach Excel, Google Sheets, Airtable oder Notion. Kostenlos loslegen.
Chrome Store Rating
PRODUCT HUNT#1 Product of the Week