Apache Tika ist das Dokumenten-Parsing-Toolkit der Apache Software Foundation: Du gibst ihm praktisch jede beliebige Datei und bekommst reinen Text plus ein normalisiertes Metadaten-Dictionary zurück. In der Projekt-README werden über tausend unterstützte Dateitypen genannt, und Tika schafft das, indem es die Spezialbibliotheken direkt mitbringt — PDFBox für PDFs, Apache POI für Office-Dokumente, jsoup für HTML, einen ODT-Reader für ODT — sodass das Ganze als einzelnes, großes Jar ausgeliefert wird und zur Laufzeit beim Parsen nichts mehr nachgeladen werden muss. In einer Datenpipeline ist es der unscheinbare erste Schritt: die Komponente vor einem Suchindex, einem E-Discovery-Review-Set oder einem LLM-Korpus, die einen heterogenen Dateihaufen in etwas Einheitliches verwandelt. Im Kern hat es zwei Aufgaben: herausfinden, was ein Byte-Stream eigentlich ist, und anschließend Text sowie Metadaten daraus 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 Modellgewichte, kein Nachinstallationsschritt — und es lief sauber auf einem brandneuen JDK, das am selben Tag auf demselben Host andere Java-Tools komplett ausgebremst hatte. Die Katalogbehauptung war aber nicht das, was ich testen wollte; die überprüfbare Frage ist enger gefasst. Was passiert Tika eigentlich, wenn die Eingabe lügt? Also habe ich einen kontrollierten Fixture-Satz gebaut, in dem jeder Inhaltsblock mit einem eindeutigen Marker-Token versehen ist, dasselbe logische Dokument in neun Trägerformate gerendert und das Ganze dann mit falschen Endungen, fehlenden Endungen, ganz ohne Dateinamen, Null-Byte-Dateien und abgeschnittenen Binärdateien angegriffen.
Die spannendste Seite zeigt sich bei der Typenerkennung. Ich habe eine PDF in .txt umbenannt und Tika gefragt, was es sei; die Antwort war application/pdf. Dann habe ich den Dateinamen komplett entfernt, die Rohdaten über stdin hineingepiped und dieselbe Antwort bekommen. Über die fünf inhaltlich erkennbaren Formate in meinem Satz hielt das in allen 20 eindeutigen logischen Bedingungen: drei Dateinamen-Varianten plus eine dateinamenlose Stream-Variante pro Format. Das Testgerüst führte den Stream-Fall dreimal unter unterschiedlichen Labels aus und erzeugte so 30 erfolgreiche Rohdurchläufe, aber diese Wiederholungen sind kein unabhängiger Beleg. PDF und RTF haben erkennbare Bytes, DOCX hat seinen Container, HTML und XML lassen sich über Markup oder Root-Inhalt identifizieren. Unterschiedliche Mechanismen, gleiches nützliches Ergebnis in diesem Fixture-Satz: Die Endung hat den Inhalt nicht überstimmt. Bei den Text-Formaten ist es anders: Markdown fällt in text/plain zurück, sobald der Dateiname falsch ist oder fehlt. Seine Identität hing hier vollständig an .md.
Zwei Grenzen vorweg zu jeder Zahl, die folgt. Ich habe Apache Tika 3.3.2 getestet — und am 27. Juli 2026 geprüft, dass dies weiterhin die neueste stabile Version war; die 4.0.0-Linie existiert auf Maven Central nur als Alpha- und Beta-Build. Das Projekt lag bei meiner Prüfung am 27. Juli 2026 bei rund 3,9k GitHub-Sternen und steht unter Apache-2.0, also ungefähr so frei von kommerziellen Hürden, wie eine Lizenz nur sein kann. Und OCR habe ich überhaupt nicht getestet. Keine einzige gescannte Seite, kein einziges bildbasiertes PDF. Tesseract und poppler waren auf der Maschine, auf der ich das ausgeführt habe, nicht installiert, also war jeder OCR-Pfad schon vor dem Start blockiert. Hier gibt es keine OCR-Zahlen, weil es schlicht keine OCR-Zahlen gibt.
Was Tika wirklich ist, wenn man den Marketingtext auf der Verpackung ignoriert
Die verbreitete Annahme ist, Apache Tika sei ein Dokumentenkonverter — man wirft ein DOCX hinein und bekommt sauberes Markdown mit intakten Überschriften und Tabellen zurück. Das ist es nicht, und je klarer das ist, desto besser wirkt das Tool.
Der hier getestete Pfad hat drei relevante Stufen: einen Content-Type-Detektor, einen Dispatcher, der die Bytes an den passenden Parser weiterreicht, und den --text-Ausgabebehälter der CLI, der Fließtext zusammen mit separat abrufbaren Metadaten ausgibt. In diesem Ausgabevertrag gibt es keine Title-Objekte, keine ListItems und kein rekonstruiertes Tabellenraster. Tika bietet außerdem andere Handler und APIs, darunter XHTML-/SAX-orientierte Ausgaben; diese habe ich nicht getestet. Jede strukturelle Aussage unten bezieht sich daher auf tika-app --text und nicht auf die Behauptung, das Toolkit habe nirgends einen strukturierten Event-Stream.
Das klingt nach einer Einschränkung, und in einer Hinsicht ist es das auch. Es bedeutet aber zugleich, dass Tika nichts falsch klassifizieren kann — und genau das ist der Tausch, den seine lauteren Verwandten in die andere Richtung eingehen.
Die Erkennung selbst läuft in einer dokumentierten Reihenfolge ab: zuerst Signatur-Bytes, dann XML-Root-Inspektion, dann Dateinamens-Glob, dann ein von Ihnen selbst übergebener Typ (Tikas eigene Erkennungsdokumentation beschreibt das so). Erst wenn der Typ feststeht, reicht der Dispatcher die Bytes an den passenden eingebetteten Parser weiter — PDFBox, POI, jsoup, TextAndCSVParser für den Textbereich.
Diese Trennung zwischen Erkennung und Parsing ist kein internes Detail. Sie ist der Grund, warum eine Datei, die sich nicht mehr sauber parsen lässt, trotzdem korrekt typisiert werden kann — und genau darin liegt Tikas praktischster Trick, sobald es anfängt zu knirschen.
Setup: ein Jar, ein Befehl und ein JVM, das nicht zickig ist
Die Installation ist ein Download. tika-app-3.3.2.jar von Maven Central ist etwa 67 MB groß — ein großes Jar, das jeden Parser bündelt — und danach genügt java -jar tika-app-3.3.2.jar --text file.pdf. Keine Config-Datei, keine Modellgewichte, kein Nachinstallieren, keine brew install-Kette.
Bei der JDK-Seite war ich überrascht. Ich habe das Ganze auf OpenJDK 26.0.1, einem brandneuen Nicht-LTS-Build, ausgeführt, und --version, --text, --metadata und --detect lieferten alle Exit 0 ohne Kompatibilitätswarnungen. Das ist erwähnenswert, weil ich am selben Host in derselben Sitzung auch Apache Nutch getestet habe und dessen Crawl-Zyklus unter JDK 26 überhaupt nicht lief — wegen der in neueren JDKs entfernten SecurityManager-Unterstützung braucht es dort ein LTS bis 21 oder darunter. Tika hat das nicht interessiert. Wenn du JVM-Tools wegen genau dieser Art von Schmerz bisher gemieden hast, ist Tika nicht der Ort, an dem es zuschlägt.
Zwei ehrliche Abzüge beim Setup: Die CLI startet bei jedem Aufruf eine frische JVM, daher ist der Kaltstart real — 131 Aufrufe in meinem Testgerüst dauerten knapp eine Minute, größtenteils JVM-Anlaufzeit. Wer Dateien in größerem Umfang verarbeitet, sollte die Bibliothek oder den Server-Modus verwenden, nicht eine Shell-Schleife über das Jar. Und die versprochene Abhängigkeit von externen Tools hat eine harte Grenze: Textlayer-Extraktion bei PDFs braucht nichts Externes, OCR aber sehr wohl tesseract und poppler. PDFs mit Textschicht, DOCX, ODT, RTF, HTML, XML, TXT, Markdown und CSV wurden auf einem Host ohne diese Binaries problemlos geparst. Gescannte Dokumente wären das nicht gewesen, und ich habe nicht so getan, als wäre es anders.
Der Kontrast zur Schwesterbibliothek unstructured, die ich am selben Tag getestet habe, war deutlich: Der Pfad für elektronische PDFs war dort komplett blockiert, weil das Importieren des PDF-Moduls den Inferenz-Stack (torch und Co.) schon beim Laden zieht — also vor dem Strategie-Dispatch, sodass selbst die „schnelle“ Strategie ohne das Paket gar nicht importiert werden kann. Tika extrahierte den Textlayer derselben PDF mit einem schlichten java -jar.
Der Test mit der lügenden Endung: Mime-Typ-Erkennung ignoriert, wie die Datei heißt

Acht Formate, jeweils mit korrekter Endung, bewusst falscher Endung oder ganz ohne Endung, plus ein dateinamenloser Byte-Stream über 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 und kam so auf 48 Rohdurchläufe; diese drei Stream-Zeilen schrumpfen zu einer Bedingung, weil stdin keinen Dateinamen mitliefert.
| Fixture | Echter Typ | Umbenannt zu | Richtige Endung | Falsche Endung | Keine Endung | Roh-Stream, ohne Dateinamen |
|---|---|---|---|---|---|---|
application/pdf | .txt | ✅ | ✅ | ✅ | ✅ | |
| DOCX | OOXML WordprocessingML | .jpg | ✅ | ✅ | ✅ | ✅ |
| RTF | application/rtf | .html | ✅ | ✅ | ✅ | ✅ |
| HTML | text/html | .csv | ✅ | ✅ | ✅ | ✅ |
| XML | application/xml | .txt | ✅ | ✅ | ✅ | ✅ |
| Reiner Text | text/plain | .pdf | ✅ | ✅ | ✅ | ✅ |
| Markdown | text/markdown | .pdf | ✅ | ❌ text/plain | ❌ text/plain | ❌ text/plain |
| CSV | text/csv | .txt | ✅ | ❌ text/plain | ❌ text/plain | ❌ text/plain |
(Die Stream-Spalte fasst alle drei Endungs-Varianten zusammen, denn ohne Dateinamen gibt es für den Glob nichts zu lesen.)
Die fünf inhaltsdetektierbaren Formate — PDF, DOCX, RTF, HTML und XML — trafen in 20 von 20 eindeutigen Bedingungen den korrekten Typ (und in 30 von 30 Rohdurchläufen, inklusive der doppelten Stream-Runs). Eine PDF namens report.txt blieb eine PDF. Eine DOCX namens photo.jpg blieb eine DOCX. Dafür war kein Dateiname nötig. Das heißt nicht, dass alle fünf dieselben festen Byte-Signaturen verwenden: PDF und RTF haben erkennbare Header, DOCX ist ein ZIP-basierter Container, und HTML/XML werden über Markup oder Root-Inhalt erkannt. In diesen Fixtures gewann die lügende Endung nicht.
Dann der Textbereich. Markdown wurde nur dann als text/markdown erkannt, wenn die .md-Endung vorhanden und lesbar war. Benennen Sie es um, entfernen Sie die Endung oder senden Sie es als Stream, fällt es in diesem Test auf text/plain zurück. CSV verhielt sich auf diesem bewusst kleinen Raster ähnlich: text/csv kam nur über den .csv-Glob zustande. Zählt man die eindeutigen Bedingungen, dann wurde Markdown und CSV jeweils nur in einer von vier Bedingungen als spezifischer Typ erkannt; reiner Text war ohnehin schon text/plain, also konnte er nicht weiter „zusammenfallen“. Das Rohgerüst mit 48 Durchläufen bleibt als Reproduzierbarkeitsnachweis nützlich, aber nicht als größerer Nenner.
Ein Detail spricht hier für Tika: Die lügende Endung gewinnt auch nicht. Mein Markdown-Fixture, auf .pdf umbenannt, kam als text/plain zurück, nicht als application/pdf. Tika glaubte der Lüge nicht; es konnte nur die Wahrheit nicht bestätigen. Ein Rückfall auf den Obertyp ist viel besser als eine selbstsicher falsche Aussage, und dass text/markdown ein dokumentierter Untertyp von text/plain ist, macht dieses Verhalten eher principled als willkürlich.
Bei CSV gibt es eine spezielle Einschränkung. Tika besitzt einen statistischen CSV-Detektor, und zur Parse-Zeit — bestätigt durch TextAndCSVParser in der X-TIKA:Parsed-By-Kette — wurde mein kleines Raster mit 2 Spalten und 3 Zeilen als text/plain statt text/csv eingestuft. Das ist eine Einzelbeobachtung an einem bewusst minimalen Fixture. Eine größere oder stärker gequotete CSV kann den Detektor durchaus auslösen. Ich behaupte nicht, dass die Inhaltsdetektion bei CSV kaputt ist; ich behaupte, dass auf diesem Raster die Endung den Ausschlag für text/csv gegeben hat.
Warum das in einer echten Upload-Pipeline wichtig ist
Das konkrete Szenario ist ein Upload-Router. Nehmen wir an, du nimmst Benutzer-Uploads an und leitest sie nach Typ weiter: PDFs an den Rechnungsparser, Tabellen an den Importer für Buchungen, alles andere in einen Textindex. Wenn du der Endung vertraust, landet eine PDF mit dem Namen notes.txt im falschen Zweig — und das ist noch der harmlose Fall; die bösartige Variante ist eine Polyglot-Datei mit freundlicher Endung.
Bei den hier getesteten Binär- und Markup-Fixtures routete Tika nach Inhalt, selbst nachdem der Dateiname verschwunden war. Das ist nützlich, wenn ein Blob-Store oder HTTP-Body-Handler den Namen verworfen hat. Dieses Ergebnis deckt allerdings weder Tikas lange Fehler-Ecke noch mehrdeutige Dateien oder Polyglots ab. Die getesteten Text-Formate verhielten sich anders: Wenn die Pipeline die Dateinamen entfernte, kamen Markdown und CSV als text/plain an, sodass Regeln, die auf ihre spezifischen Medientypen zielten, nicht mehr griffen. Den Originalnamen sollte man also als Sidecar-Metadatum mitführen und nicht darauf hoffen, dass die Inhaltsdetektion ihn rekonstruieren kann.
Der eingepflanzte Inhalt blieb erhalten. --text machte die Struktur platt.
Die zweite Achse ist die Treue zum Inhalt, und sie teilt sich sauber in zwei Bereiche. Ich habe ein kanonisches Dokument (Überschriften, zwei Absätze, eine Aufzählung, eine nummerierte Liste, einen abschließenden Absatz) in HTML, Markdown, Plain Text, DOCX, PDF, RTF, ODT und XML gerendert, plus ein Tabellendokument in HTML, Markdown, Text, DOCX, CSV und XML. Vierzehn Träger-Renderings. Jeder Block trägt ein eindeutiges Token — zztitle1, zzitem3, zztblcell_beta und so weiter — sodass „überlebt“ versus „verloren“ ein exakter Substring-Check ist und keine Ermessensfrage.
Das Recall der Marker-Tokens lag bei allen vierzehn Renderings bei 1,000. Kein einziges eingepflanztes Token ging verloren: Jede markierte Tabellenzelle, jeder Listeneintrag und jede Überschrift war vorhanden. Drei lokale Wiederholungen pro Träger nach dem Warmup lieferten byte-identische --text-Ausgaben. Dieses Kriterium sagt nichts über nicht markierte Zeichen, Reihenfolge, Leerzeichen, Unicode-Normalisierung, wiederholte Inhalte, Links, Header, Fußnoten oder eingebettete Objekte aus. Es ist ein Präsenztest auf Blockebene, kein Beweis vollständiger Dokumenttreue.
Die Ausgabe als Fließtext gibt den Großteil der Quellstruktur auf.
So kommt das HTML-Tabellendokument aus --text heraus:
Tool Durchsatz
zztblcell_alpha 120
zztblcell_beta 95
Durch Tabs getrennte Zeilen. Die Kopfzeile ist nicht als Kopfzeile markiert. Es gibt kein Raster, keine Zellgrenzen außer einem Tab, keine Möglichkeit zu erkennen, dass es jemals eine <table> war. Die DOCX-Tabelle wird auf genau dieselbe Weise geglättet.
Listen sind subtiler und hängen davon ab, was der Quelltext tatsächlich enthalten hat:
| Was die Aufzählung im Quellformat war | Träger | Was --text zurückgibt |
|---|---|---|
Ein wörtliches Zeichen — diese Renderings schrieben - als echten Text | Plain Text, Markdown, RTF, ODT, PDF | das - bleibt erhalten, weil Tika nur Zeichen durchreicht |
Echte Struktur — ein HTML <li>, eine DOCX-Listenstilvorlage „List Bullet“ | HTML, DOCX | das Markerzeichen verschwindet komplett und es bleibt nur der Text übrig: in HTML tab-eingerückt, in DOCX als schlichte Zeile ohne sichtbare Markierung |
Tika rendert nie ein Markerzeichen neu, das es nicht als Text erhalten hat. Gleicher Inhalt in beiden Fällen; unterschiedlich wirkende Ausgabe.
Der Markdown-Fall macht das besonders klar. Wenn du Tika eine .md-Datei mit einer Pipe-Tabelle gibst, kommen die Pipes wortwörtlich zurück, was so aussieht, als wäre die Struktur erhalten geblieben. Ist sie aber nicht. Tika hat es als Text gelesen und die Bytes zurückgereicht. Niemand hat diese Tabelle verstanden.
Der gemessene Vertrag ist also enger: Alle eingepflanzten Marker blieben erhalten, aber --text bewahrte weder typisierte Elemente noch ein rekonstruierbares Tabellenraster. Das als Parser-Defekt zu bezeichnen, würde den Kern verfehlen. Die Fließtextextraktion vermeidet bewusst das Problem der Elementklassifizierung; sie kann damit aber auch nicht die Anforderungen eines Downstream-Systems erfüllen, das genau diese Elementtypen braucht. Wenn du typisierte Blöcke oder rekonstruierte Tabellen benötigst, ist --text nur eine Komponente im Stack, nicht der ganze Stack. Andere Tika-Handler können mehr Struktur liefern, lagen aber außerhalb dieses Laufs.
Die Standard-Einschränkung zu allen Treuezahlen hier: Sie stammen aus kontrollierten synthetischen Fixtures auf einer Maschine, einer Version, einem JDK. Sie zeigen, dass die markierten Blöcke in der Ausgabe vorhanden waren. Sie belegen keine Zeichen-für-Zeichen-Treue oder Korrektheit auf einem unordentlichen realen Korpus.
Metadaten: normalisiert und erfreulich unwillig zu erfinden

Ich habe bekannte Werte für Autor, Titel und Erstellungsdatum in jeden Träger mit Metadatenebene eingebettet und anschließend geprüft, was zurückkam.
| Träger | author → dc:creator | title → dc:title | created → dcterms:created |
|---|---|---|---|
HTML (<meta name=author>, <title>) | ✅ | ✅ | nicht eingebettet |
| DOCX (Core Properties) | ✅ | ✅ | ✅ exakt 2021-03-15T09:30:00Z |
| PDF (Info-Dict) | ✅ | ✅ | vorhanden, aber es war der Zeitstempel des Generators — nicht gewertet |
ODT (meta.xml) | ✅ | ✅ | ✅ exakt 2021-03-15T09:30:00Z |
| TXT / MD / CSV / RTF / XML | keine Metadatenebene | — | — |
Autor und Titel wurden auf 4 von 4 metadatenfähigen Trägern wiederhergestellt — und das Schöne daran: 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 einen Consumer, nicht vier.
created ist die ehrliche Unschärfe. DOCX und ODT gaben meinen exakt eingebetteten Zeitstempel von 2021 zurück. Das PDF lieferte ein Erstellungsdatum, aber es war das Datum, das meine Generatorbibliothek beim Erstellen gesetzt hatte, nicht der Wert, den ich eigentlich einbetten wollte — daher werte ich es als vorhanden, nicht als wiederhergestellt. Und die Formate ohne Metadatenebene lieferten gar nichts, was die richtige Antwort ist. Tika erfindet keinen Autor aus dem Textkörper.
Vorsätzlich kaputt machen und die daraus entstehende Triage-Technik
Vier feindliche Eingaben. Eine Null-Byte-Datei. Eine gültige PDF-Headerstruktur mit abgeschnittenem Body. Ein abgeschnittenes DOCX-ZIP. Und eine UTF-8-Datei mit Mehrbyte-Zeichen ohne BOM und ohne Encoding-Deklaration. Das sind lokale Fixture-Formen, keine Tika-Grenzwerte.
Das zugrunde liegende Testgerüst, die erzeugten Fixtures, die Roh-JSON-Daten, der Jar-Checksum und das Environment-Manifest sind hier nicht öffentlich verlinkt, sodass ein Außenstehender die genauen Nenner nicht unabhängig reproduzieren kann. Behandle die Tabellen daher als berichtete Beobachtungen und nicht als von Dritten verifizierbare Belege.
| Eingabe | --text / --json | Fehler | --detect |
|---|---|---|---|
| 0-Byte-Datei | Exit 1, leere stdout | ZeroByteFileException: InputStream must have > 0 bytes | Exit 0 → text/plain mit Dateiname, application/octet-stream aus Stream |
| Abgeschnittene PDF | Exit 1, leere stdout | TikaException: TIKA-198: Illegal IOException from PDFParser | Exit 0 → application/pdf |
| Abgeschnittene DOCX | Exit 1, leere stdout | POI FATAL: "XML document structures must start and end within the same entity" | Exit 0 → OOXML-Typ |
| UTF-8, kein BOM, keine Deklaration | Exit 0 | nichts | Exit 0 → text/plain, Charset UTF-8 |
Extraktion scheitert laut, und diese Fehler haben dieselbe äußere Form. Die Null-Byte-Datei, die abgeschnittene PDF und die abgeschnittene DOCX erzeugten jeweils eine Exception, Exit 1 und leere stdout. Die CLI schluckt den Fehler also nicht in ein hübsches leeres Ergebnis. Prozesssicher in diesen Fällen — kein Hänger, kein Segfault — aber der Aufrufer muss Exit-Status und stderr prüfen und darf nicht nur auf einen leeren String schauen.
Erkennung ist vom Parsing entkoppelt. Bei beiden abgeschnittenen Binärdateien gab --detect Exit 0 mit dem erwarteten Typ aus dem intakten Anfangsteil zurück; der Parser scheiterte erst am defekten Body. Eine Pipeline kann Erkennung daher als separates Triage-Signal vor oder nach einem fehlgeschlagenen Parse nutzen. Ob „Detect zuerst“ der richtige Standard 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 womöglich der falsche Kompromiss.
Charset-Erkennung funktioniert. Die UTF-8-Datei ohne BOM und ohne Deklaration wurde als UTF-8 dekodiert, und 日本語テスト kam unverändert durch. Eine kleine Einschränkung für alle, die die Metadaten-Dicts lesen: Meine reinen ASCII-Fixtures melden charset=ISO-8859-1, was sich auf ASCII-Bytes nicht von UTF-8 unterscheiden lässt. Das ist kein Fehlgriff, sondern ein Unentschieden.
Tika neben unstructured: gleiche Dateitypen, andere Aufgabe
Beide wurden in derselben Research-Session getestet, aber das hier ist eine Taxonomie von Ausgabeverträgen und kein symmetrischer Benchmark. Die Tools wurden auf unterschiedliche Ergebnisse hin bewertet.
Verwandte Besprechung: Unstructured-Review.
| Apache Tika | unstructured | |
|---|---|---|
| Woran ich es gemessen habe | Inhalts-Treue: Ist etwas verloren gegangen? | Element-Klassifizierungs-Treue: Hat jeder Block den richtigen Typ bekommen? |
| Ergebnis | alle eingepflanzten Marker in allen vierzehn Renderings vorhanden | im separaten Klassifizierungs-Test hatte eine Plain-Text-Tabelle einen Table-Recall von 0,000, und eine Überschrift mit Verb wurde als narrative Text klassifiziert |
| Zurückgegebene typisierte Elemente | keine — es kam keinerlei Struktur zurück | Title, NarrativeText, ListItem, Table — genau das, was Tika bewusst nicht tut |
| OCR | auf meinem Host blockiert, Tesseract fehlte | auf meinem Host blockiert, Tesseract fehlte |
Flacher, markererhaltender Output versus typisierte Elemente mit beobachtbaren Klassifizierungsfehlern. Wähle nach dem, was das Downstream-System braucht. Wenn es ein Suchindex oder ein LLM-Kontextfenster ist, reicht flacher Text oft aus. Wenn es auf Elementtypen angewiesen ist, kann Tikas --text-Pfad diesen Vertrag nicht liefern.
Keiner von beiden hat 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 inhaltsdetektierbaren Fixtures; auch die doppelten Stream-Runs stimmten überein.
- Alle eingepflanzten Marker überlebten in allen 14 Carrier-Renderings, inklusive markierter Tabellenzellen und Listeneinträge.
- Drei lokale Wiederholungen waren reproduzierbar: Jeder Träger lieferte innerhalb dieser Umgebung byte-identischen Text zurück.
- Metadaten wurden formatübergreifend normalisiert —
dc:creator/dc:title/dcterms:createdunabhängig vom Ausgangsformat, wiederhergestellt auf 4/4 metadatenfähigen Trägern. - Für die von mir getesteten Formate tatsächlich frei von externen Abhängigkeiten: PDF-Textlayer, DOCX, ODT, RTF, HTML parsen aus einem Jar ohne externe Binaries.
- Läuft sauber auf OpenJDK 26 — keine LTS-Beschränkung.
- Die Erkennung bleibt auch bei abgeschnittenen Binärdateien korrekt (Exit 0) und liefert damit ein zuverlässiges Triage-Signal, wenn das Parsing scheitert.
- Apache-2.0, ausgereift, aktiv gepflegt.
Nachteile
- Markdown- und CSV-Erkennung hängen vollständig vom Dateinamen ab; 10 von 18 signaturlosen Feldern fielen auf
text/plainzurück, sobald der Name fehlte oder falsch war. --textgibt keine Elementtypen zurück; Tabellen werden zu tab-getrennten Zeilen und strukturelle Listenmarker verschwinden.- Extraktion wirft bei leeren und beschädigten Eingaben ungefangen; beide Fälle sehen allein aus der Extraktionsaufruf-Stelle heraus identisch aus.
- 67-MB-Jar plus JVM-Kaltstart pro Aufruf im CLI-Modus.
- OCR und gescannte Bild-PDFs sind hier vollständig ungetestet — Tesseract und poppler fehlten, also wird über diesen Pfad keinerlei Aussage getroffen.
- Jede Zahl hier basiert auf synthetischem Ground Truth auf einer Maschine, einer Version. Reale Korpusgenauigkeit, verschlüsselte Dateien, eingebettete/rekursive Dokumente und Durchsatz in großem Maßstab wurden nicht gemessen.
Für wen das sinnvoll ist — und für wen nicht
Tika passt, wenn deine Eingaben Dateien sind, die du bereits hast, und deine Ausgabe Text plus Metadaten sein soll, die von einer Maschine indiziert werden können. Suchindizierung, E-Discovery, Archivverarbeitung, das Einspeisen eines Korpus in ein LLM, die Content-Type-Validierung in einer Upload-Pipeline. Es ist nützlich als erster Triage- und Normalisierungsschritt vor etwas Smarterem: Die getesteten Typen erkennen, Fließtext extrahieren und mit klaren Prüfungen für Inhalte weiterreichen, die deine Pipeline nicht verlieren darf.
Spar es dir — genauer: hör nicht bei --text auf — wenn du typisierte Elemente, rekonstruierte Tabellen oder Layout benötigst. Spar es dir auch, wenn deine Dokumente Scans sind, zumindest solange bis du Tesseract installiert und eigene Zahlen erhoben hast, denn ich habe keine. Für Arbeit mit hohem Volumen solltest du die Bibliothek oder den Servermodus gegen die CLI mit repräsentativen Dokumenten benchmarken. Der Prozess-Start war in diesem kleinen Datei-Setup sichtbar, aber Durchsatz und Ressourcenverbrauch wurden nicht gemessen.
Der Punkt, an dem viele stolpern: Wenn deine Speicherschicht Dateinamen entfernt und du Markdown oder CSV verarbeitest, verlasse dich nicht darauf, dass Tika diese von Plain Text unterscheiden kann. Behalte den Originalnamen bei.
Alternativen und wo Thunderbit einzuordnen ist
Zuerst die faire Einordnung, denn der ehrliche Vergleich hier betrifft die Eingaben, nicht die 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 ruft keine Seiten ab, führt kein JavaScript aus, kämpft nicht mit Anti-Bot-Schutz und gibt auch nicht vor, das zu tun.
Genau dort, wo diese Grenze liegt, kann ein verwalteter Web-Extraktionsdienst, einschließlich unseres eigenen Thunderbit, Teil der Architektur werden: Er holt Live-Seiten ab, während Tika Dateien parst, die bereits in deinem Besitz sind. Dieser Artikel hat diese Dienste nicht gegen Tika benchmarked, und sie sind kein Ersatz für dieselbe Eingabe.
Die klare Trennung: Tika für Dokumente, die du bereits besitzt, eine verwaltete Extraktions-API für Webseiten, die du erst noch abrufen musst. Viele Pipelines nutzen beides — Crawling und Extraktion auf der Web-Seite, Tika für PDFs und DOCX-Anhänge, die zurückkommen.
Wenn du den größeren Open-Source-Bereich vergleichen willst, habe ich den vollständigen Open-Source-Scraper-Vergleich, eine Übersicht der nützlichsten Scraping-Projekte auf GitHub, einen praxisnahen Crawl4AI-Test zur browsergestützten Markdown-Methode und einen breiteren Überblick über Scraping-Tools veröffentlicht. Für den No-Code-Weg gibt es außerdem eine Anleitung, wie man eine Website mit KI scrapen kann.
Thunderbit für Web-Datenextraktion ausprobieren
Fazit
Sollte man Apache Tika verwenden? Ja — wenn deine Aufgabe darin besteht, heterogene Dateien in Fließtext und normalisierte Metadaten zu überführen, und wenn du die Felder oder Marker validierst, die deine eigene Pipeline nicht verlieren darf.
Der Detektor war die stärkste Seite dieses Laufs. Er lieferte in 20 von 20 eindeutigen Bedingungen für die fünf inhaltsdetektierbaren Fixtures den erwarteten Typ zurück, inklusive dateinamenloser Streams. Alle eingepflanzten Marker überlebten über vierzehn Renderings, und die Ausgabe wiederholte sich in drei lokalen Wiederholungen bytegenau. Nützlicher Beleg. Trotzdem synthetischer Beleg. Dass das aus einem Jar auf diesem JDK lief, ohne externe Binaries für die getesteten Nicht-OCR-Pfade, machte das Deployment angenehm unspektakulär.
Man sollte es aber richtig einordnen. Jede Tabelle, die du hineingibst, kommt als tab-getrennte Zeilen zurück. Jeder strukturelle Listenmarker verschwindet. Markdown und CSV verlieren ihre Identität in dem Moment, in dem der Dateiname weg ist. Leere und beschädigte Dateien werfen dieselbe Fehlerform, und um sie auseinanderzuhalten, braucht man den separaten Detect-Aufruf. Und bei OCR — der Frage, die viele Tika-Nutzer am meisten interessiert — habe ich nichts anzubieten: Ich konnte es nicht ausführen, und ich werde nicht spekulieren.
Innerhalb dieser Grenzen erledigt Tika seine unglamouröse Arbeit mit ungewöhnlicher Verlässlichkeit. Es liest die Bytes, nicht das Etikett auf der Verpackung. Nur die Form der Bytes soll man ihm nicht zuschreiben.
Thunderbit für Web-Datenextraktion ausprobieren Get Started Free
FAQs
Erkennt Apache Tika Dateitypen korrekt, wenn die Endung falsch ist?
Für die hier getesteten fünf inhaltsdetektierbaren Fixtures: ja. PDF, DOCX, RTF, HTML und XML wurden in allen 20 eindeutigen logischen Bedingungen (30 Rohdurchläufe mit doppelten Stream-Executions) dem erwarteten Medientyp zugeordnet, auch bei irreführenden Endungen, ohne Endung und bei dateinamenlosen Streams. Eine PDF namens .txt wurde weiterhin als application/pdf erkannt. Markdown und das kleine CSV-Fixture waren dagegen vom Dateinamen abhängig und fielen auf text/plain zurück, sobald dieser fehlte oder falsch war.
Bewahrt Tika Tabellen und Dokumentstruktur?
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-Listenstil „List Bullet“) verschwanden. Alle eingepflanzten Marker blieben über alle 14 Carrier-Renderings erhalten, aber das beweist keine vollständige Inhalts-Treue, und --text liefert keine Elementtypen. Für typisierte Elemente oder rekonstruierte Tabellen solltest du einen anderen Tika-Ausgabe-Handler testen oder ein anderes Tool ergänzend einsetzen.
Kann Apache Tika OCR für gescannte PDFs?
Tika unterstützt OCR über Tesseract, aber ich habe das nicht getestet, und keines dieser Ergebnisse ist eine Aussage darüber. Tesseract und poppler fehlten auf meinem Testsystem, daher war jeder OCR- und gescannte-Bild-Pfad schon vor dem Start blockiert. In diesem Test gibt es nirgends OCR-Zahlen. Wenn OCR dein Anwendungsfall ist, installiere Tesseract und benchmarke es selbst — betrachte diesen Teil von Tika hier als unverifiziert.
Was macht Tika mit leeren oder beschädigten Dateien?
Es scheitert laut statt still. Eine 0-Byte-Datei wirft ZeroByteFileException; eine abgeschnittene PDF wirft eine TikaException aus dem PDFParser; eine abgeschnittene DOCX wirft einen POI-XML-Fehler. Alle drei beenden sich mit Exit 1 und leerer stdout, sodass leer und beschädigt allein über den Extraktionsaufruf nicht zu unterscheiden sind. Die Erkennung bleibt aber robust — --detect lieferte bei beiden abgeschnittenen Binärdateien Exit 0 mit dem korrekten Typ zurück, was sie zu einem zuverlässigen Triage-Schritt macht, bevor du Zeit in einen Parse investierst.
Was wurde im Tika-Test nicht abgedeckt?
Vier Dinge, ausdrücklich. OCR und gescannte Bilder (blockiert, nicht getestet). Reale Korpusgenauigkeit — alle Ergebnisse stammen aus kontrollierten synthetischen Fixtures mit eingepflanzten Marker-Tokens, also Treue gegenüber bekannten Labels statt Genauigkeit auf unordentlichen realen Dokumenten. Ressourcenverbrauch, Durchsatz und Spitzenarbeitsspeicher, die ich nicht gemessen habe. Und der lange Schwanz der „tausend Dateitypen“-Behauptung: Ich habe neun repräsentative, abhängigkeitsfreie Formate getestet, nicht den vollständigen Katalog. Alles hier ist Tika 3.3.2 auf OpenJDK 26.0.1, macOS arm64, Einzelmaschine.


