Apache Tika, c’est la boîte à outils d’analyse de documents de l’Apache Software Foundation : tu lui donnes un fichier dans presque n’importe quel format, et il te renvoie du texte brut plus un dictionnaire de métadonnées normalisées. Le README du projet annonce plus d’un millier de types de fichiers pris en charge, et Tika y arrive en intégrant directement ses bibliothèques spécialisées — PDFBox pour les PDF, Apache POI pour les documents Office, jsoup pour le HTML, un lecteur ODF pour les ODT — de sorte que tout est distribué dans un gros JAR autonome, sans rien télécharger au moment de l’analyse. Dans une chaîne de traitement de données, c’est l’étape discrète mais indispensable : le composant placé devant un moteur de recherche, un lot de revue e-discovery ou un corpus pour LLM, qui transforme un ensemble hétérogène de fichiers en quelque chose d’uniforme. En pratique, il fait deux choses : identifier ce qu’est un flux d’octets, puis en extraire le texte et les métadonnées.
C’est l’outil le moins exigeant que j’aie installé depuis longtemps. Un seul JAR, java -jar tika-app-3.3.2.jar --text file.pdf, aucun fichier de configuration, aucun poids de modèle, aucune étape post-installation, et il a tourné sans broncher sur un JDK de toute dernière génération qui avait mis à genoux d’autres outils Java sur la même machine, le même après-midi. Mais je ne voulais pas juste vérifier l’argument du catalogue ; la vraie question est plus précise. Quand l’entrée vous ment, que fait vraiment Tika ? J’ai donc monté un jeu de tests contrôlé où chaque bloc de contenu porte un jeton marqueur unique, j’ai rendu le même document logique dans neuf formats de conteneur, puis j’ai soumis l’ensemble à de fausses extensions, des extensions manquantes, des fichiers sans nom, des fichiers de zéro octet et des binaires tronqués.
La détection, c’est là que le comportement intéressant se joue. J’ai renommé un PDF en .txt et demandé à Tika ce que c’était ; il a répondu application/pdf. J’ai ensuite supprimé complètement le nom de fichier, envoyé les octets bruts sur stdin, et obtenu la même réponse. Sur les cinq formats détectables par le contenu présents dans mon jeu de tests, cela s’est vérifié dans 20 conditions logiques uniques : trois conditions liées au nom de fichier, plus une condition de flux sans nom par format. Le banc d’essai a exécuté le cas de flux trois fois sous des libellés différents, produisant 30 exécutions brutes réussies, mais ces répétitions ne comptent pas comme des preuves indépendantes. PDF et RTF exposent des octets reconnaissables ; DOCX expose son conteneur ; HTML et XML peuvent être identifiés via le balisage ou le contenu racine. Des mécanismes différents, mais le même résultat utile dans ce jeu de tests : l’extension n’a pas pris le dessus sur le contenu. Et puis il y a la famille texte, où Markdown tombe en text/plain dès que le nom de fichier est faux ou absent. Là, son identité reposait entièrement sur .md.
Deux précisions encadrent tous les chiffres qui suivent. J’ai testé Apache Tika 3.3.2 — vérifié le 27 juillet 2026, c’était toujours la dernière version stable ; la branche 4.0.0 n’existait alors qu’en builds alpha et beta sur Maven Central. Le projet comptait environ 3,9 k étoiles GitHub lors de ma vérification du 27 juillet 2026, et il est sous licence Apache-2.0, ce qui est à peu près aussi peu contraignant que possible sur le plan commercial. Et je n’ai pas testé l’OCR du tout. Pas une page scannée, pas un PDF composé uniquement d’images. Tesseract et poppler ne sont pas installés sur la machine utilisée, donc tous les chemins OCR étaient bloqués avant même de commencer. Il n’y a aucun chiffre OCR ici, tout simplement parce qu’il n’y a aucun chiffre OCR.
Ce qu’est Tika, une fois qu’on a cessé de lire le marketing sur la boîte
L’idée reçue la plus courante, c’est qu’Apache Tika serait un convertisseur de documents — on lui donne un DOCX, on récupère un Markdown propre avec titres et tableaux intacts. Ce n’est pas son rôle, et plus c’est clair, mieux l’outil apparaît.
Le parcours testé ici comporte trois étapes pertinentes : un détecteur de type de contenu, un dispatcher qui envoie les octets vers le bon parseur, et le traitement de sortie --text de la CLI, qui produit du texte plat avec des métadonnées accessibles à part. Dans ce contrat de sortie, pas d’objets Title, pas de ListItem, pas de grille de tableau reconstituée. Tika expose aussi d’autres gestionnaires et API, y compris une sortie orientée XHTML/SAX ; je ne les ai pas testés. Toutes les conclusions structurelles ci-dessous concernent donc tika-app --text, et non l’idée que la boîte à outils n’aurait jamais de flux d’événements structuré.
Ça ressemble à une limite, et sur un point, c’en est une. Mais ça veut aussi dire que Tika n’a rien à mal classer, ce qui est précisément le compromis que ses cousins plus bavards font dans l’autre sens.
La détection elle-même suit un ordre documenté : d’abord les signatures d’octets, puis l’inspection de la racine XML, ensuite le glob du nom de fichier, puis tout type que vous auriez fourni vous-même (la documentation de détection de Tika le détaille). Ce n’est qu’une fois le type résolu que le dispatcher transmet les octets au parseur intégré correspondant — PDFBox, POI, jsoup, TextAndCSVParser pour la famille texte.
Cette séparation entre détection et analyse n’est pas un détail interne. C’est la raison pour laquelle un fichier trop abîmé pour être analysé peut malgré tout être typé correctement, et c’est le tour le plus pratique que Tika offre dès que les choses commencent à se casser.
Configuration : un JAR, une commande, et un JVM peu difficile
L’installation, c’est un téléchargement. tika-app-3.3.2.jar depuis Maven Central pèse environ 67 Mo — un JAR autonome qui regroupe tous les parseurs — et ensuite, il suffit de lancer java -jar tika-app-3.3.2.jar --text file.pdf. Pas de fichier de config, pas de poids de modèle, pas d’étape post-installation, pas de chaîne brew install à enchaîner.
L’histoire du JDK m’a surprise. J’ai fait tourner l’ensemble sur OpenJDK 26.0.1, une build non-LTS de pointe, et --version, --text, --metadata et --detect sont tous revenus avec un code de sortie 0, sans plainte de compatibilité. Ça mérite d’être mentionné, parce que j’ai testé Apache Nutch sur la même machine, au même moment, et son cycle de crawl refusait totalement de tourner sur JDK 26 — il faut un LTS 21 ou inférieur, à cause de la suppression de SecurityManager dans les JDK récents. Tika, lui, s’en fichait. Si vous évitez les outils JVM à cause de ce genre de galère, Tika n’est pas là où elle vous mord.
Deux constats honnêtes côté installation. La CLI lance un nouveau JVM à chaque invocation, donc le démarrage à froid est bien réel — les 131 invocations de mon banc de test ont pris environ une minute, majoritairement en échauffement JVM. Si vous traitez des fichiers à grande échelle, mieux vaut utiliser la bibliothèque ou le mode serveur, pas une boucle shell autour du JAR. Et l’idée d’une dépendance minimale a une limite nette : l’extraction du texte des PDF ne nécessite rien d’externe, mais l’OCR a besoin de tesseract et de poppler. Les PDF avec couche texte, DOCX, ODT, RTF, HTML, XML, TXT, Markdown et CSV ont tous été analysés sur une machine sans ces outils. Les documents scannés, eux, ne l’auraient pas été, et je ne vais pas prétendre le contraire.
Le contraste est encore plus net avec la bibliothèque sœur que j’ai testée le même jour, unstructured, dont le chemin PDF électronique était totalement bloqué parce qu’importer son module PDF chargeait la pile d’inférence (torch et assimilés) dès l’import — avant même le dispatch de stratégie, donc même la stratégie « rapide » ne pouvait pas être importée sans ça. Tika a extrait la couche texte du même PDF avec un simple java -jar.
Le test des extensions mensongères : une détection MIME qui ignore le nom de fichier

Huit formats, chacun présenté avec une extension correcte, une extension volontairement fausse, ou aucune extension, plus un flux binaire sans nom sur stdin. Cela représente 32 conditions logiques uniques. Le banc d’essai initial a aussi exécuté les mêmes octets de flux une fois sous chaque libellé de fichier, pour un total de 48 exécutions brutes ; ces trois lignes de flux se réduisent à une seule condition, puisque stdin n’a pas de nom de fichier.
| Fixture | Vrai type | Renommé en | Extension correcte | Extension mensongère | Sans extension | Flux brut, sans nom de fichier |
|---|---|---|---|---|---|---|
application/pdf | .txt | ✅ | ✅ | ✅ | ✅ | |
| DOCX | OOXML wordprocessingml | .jpg | ✅ | ✅ | ✅ | ✅ |
| RTF | application/rtf | .html | ✅ | ✅ | ✅ | ✅ |
| HTML | text/html | .csv | ✅ | ✅ | ✅ | ✅ |
| XML | application/xml | .txt | ✅ | ✅ | ✅ | ✅ |
| Texte brut | text/plain | .pdf | ✅ | ✅ | ✅ | ✅ |
| Markdown | text/markdown | .pdf | ✅ | ❌ text/plain | ❌ text/plain | ❌ text/plain |
| CSV | text/csv | .txt | ✅ | ❌ text/plain | ❌ text/plain | ❌ text/plain |
(La colonne flux regroupe les trois conditions d’extension, car sans nom de fichier il n’y a rien pour le glob.)
Les cinq formats détectables par le contenu — PDF, DOCX, RTF, HTML et XML — ont obtenu le bon type dans 20 conditions uniques sur 20 (et 30 exécutions brutes sur 30, en incluant les répétitions de flux). Un PDF nommé report.txt est resté un PDF. Un DOCX nommé photo.jpg est resté un DOCX. Aucun n’avait besoin d’un nom de fichier. Ça ne veut pas dire que les cinq utilisent tous des signatures d’octets fixes : PDF et RTF ont des en-têtes reconnaissables, DOCX est un conteneur basé sur ZIP, et HTML/XML sont détectés à partir du balisage ou du contenu racine. Des mécanismes différents, mais dans ce jeu de tests, le mensonge de l’extension n’a pas gagné.
Puis vient le régime des formats texte. Markdown n’a été reconnu comme text/markdown que lorsque l’extension .md était présente et lisible. Renommez-le, supprimez l’extension ou envoyez-le sous forme de flux, et il est retombé en text/plain dans ce test. CSV s’est comporté pareil sur cette grille volontairement minimale : text/csv n’apparaissait qu’avec le glob .csv. En comptant les conditions uniques, Markdown et CSV n’ont chacun été résolus comme type spécifique que dans une condition sur quatre ; le texte brut était déjà text/plain, donc il n’y avait rien à quoi il puisse « se réduire ». Le banc d’essai brut à 48 exécutions reste utile comme trace de répétabilité, mais pas comme dénominateur plus large.
Un détail joue en faveur de Tika ici : l’extension mensongère ne gagne pas non plus. Mon fixture Markdown renommé en .pdf est revenu text/plain, pas application/pdf. Tika n’a pas cru au mensonge ; il n’a simplement pas pu confirmer la vérité. Revenir au type parent est une bien meilleure erreur que d’affirmer avec assurance un type faux, et le fait que text/markdown soit un sous-type documenté de text/plain rend ce repli logique plutôt qu’arbitraire.
Il y a une nuance pour CSV. Tika dispose d’un détecteur statistique pour CSV, et au moment de l’analyse — confirmé par la présence de TextAndCSVParser dans la chaîne X-TIKA:Parsed-By — ma petite grille de 2 colonnes par 3 lignes a été résolue en text/plain plutôt qu’en text/csv. C’est une seule observation sur un fixture délibérément minimal. Un CSV plus vaste ou avec des guillemets pourrait très bien déclencher le détecteur. Je ne dis pas que la détection de CSV par contenu est cassée ; je dis que, sur cette grille, c’est l’extension qui a produit text/csv.
Pourquoi c’est important dans un vrai pipeline d’upload
Le scénario concret, c’est un routeur de fichiers déposés. Imagine que tu acceptes des uploads utilisateur et que tu les routes par type : les PDF vers le parseur de factures, les tableurs vers l’importateur comptable, tout le reste vers un index texte. Si tu fais confiance à l’extension, un PDF nommé notes.txt partira dans la mauvaise branche — et ça, c’est encore le cas bénin ; la version hostile est un fichier polyglotte avec une extension rassurante.
Pour les fixtures binaires et de balisage testées ici, Tika a routé selon le contenu même après disparition du nom de fichier, ce qui est utile quand un stockage d’objets ou un gestionnaire de corps HTTP l’a supprimé. Ce résultat ne couvre ni la longue traîne de Tika, ni les fichiers ambigus, ni les polyglottes. Les fixtures texte testées se sont comportées différemment : lorsque le pipeline supprimait les noms de fichier, Markdown et CSV arrivaient en text/plain, donc les règles basées sur leurs types MIME spécifiques cessaient de s’appliquer. Garde le nom d’origine comme métadonnée annexe au lieu d’espérer que la détection de contenu le reconstitue.
Le contenu injecté a survécu. --text a aplati la structure.
La fidélité est le deuxième axe, et elle se divise nettement en deux. J’ai rendu un document canonique (titres, deux paragraphes, une liste à puces, une liste numérotée, un paragraphe de clôture) en HTML, Markdown, texte brut, DOCX, PDF, RTF, ODT et XML, ainsi qu’un document de tableau en HTML, Markdown, texte, DOCX, CSV et XML. Quatorze rendus de conteneurs. Chaque bloc porte un jeton unique — zztitle1, zzitem3, zztblcell_beta, etc. — de sorte que « survie » ou « disparition » se vérifie par sous-chaîne exacte, pas à l’appréciation.
Le rappel des jetons marqueurs est revenu à 1,000 sur les quatorze rendus. Aucun jeton injecté n’a disparu : chaque cellule de tableau étiquetée, chaque élément de liste et chaque titre étaient présents. Trois répétitions locales par conteneur, après échauffement, ont renvoyé une sortie --text identique octet pour octet. Cet oracle ne dit rien des caractères non marqués, de l’ordre, des espaces, de la normalisation Unicode, du contenu répété, des liens, en-têtes, notes de bas de page ou objets incorporés. C’est un contrôle de présence de blocs, pas une preuve de fidélité documentaire complète.
La sortie en texte plat abandonne la majeure partie de la structure source.
Voici le document HTML de tableau tel qu’il ressort de --text :
Tool Throughput
zztblcell_alpha 120
zztblcell_beta 95
Des lignes jointes par des tabulations. La ligne d’en-tête n’est pas marquée comme telle. Il n’y a pas de grille, pas de frontières de cellules au-delà d’une tabulation, aucun moyen de savoir qu’il s’agissait d’un <table>. Le tableau DOCX s’aplatit de la même façon.
Les listes sont plus subtiles, et elles se séparent selon ce que contenait réellement la source :
| Ce que la puce représentait dans la source | Conteneurs | Ce que renvoie --text |
|---|---|---|
Un caractère littéral — ces rendus écrivaient tous - comme texte réel | texte brut, Markdown, RTF, ODT, PDF | le - reste, car Tika transmet les caractères |
Une vraie structure — un <li> HTML, un style DOCX List Bullet | HTML, DOCX | le marqueur disparaît complètement et vous n’obtenez que le texte de l’élément : indenté par tabulation en HTML, ligne simple sans ornement en DOCX |
Tika ne recrée jamais un marqueur qu’il n’a pas reçu comme texte. Même contenu, rendu différent.
Le cas Markdown l’illustre bien. Donne à Tika un fichier .md contenant un tableau à barres verticales, et les barres reviennent verbatim, ce qui donne l’impression d’une préservation de structure. En réalité, ce n’est pas le cas. Tika l’a lu comme du texte et a renvoyé les octets. Rien n’a compris ce tableau.
Le contrat mesuré est donc plus étroit : tous les marqueurs injectés ont survécu, tandis que --text n’a pas préservé les éléments typés ni une grille de tableau reconstituable. Appeler ça un défaut de parseur serait à côté de la plaque. L’extraction plate évite volontairement le problème de classification des éléments ; elle ne peut pas non plus satisfaire un consommateur aval qui a besoin de ces types d’éléments. Si tu veux des blocs typés ou des tableaux reconstruits, --text n’est qu’un composant de la chaîne, pas la chaîne complète. D’autres gestionnaires Tika peuvent exposer davantage de structure, mais ils sortaient du cadre de cette exécution.
Mise en garde habituelle sur tous les chiffres de fidélité ici : ils proviennent de fixtures synthétiques contrôlées, sur une machine, une version et un JDK. Ils montrent que les blocs marqués étaient présents dans la sortie. Ils ne démontrent pas une préservation caractère par caractère ni une exactitude sur un corpus réel et chaotique.
Métadonnées : normalisées, et agréablement réticentes à inventer

J’ai intégré des valeurs connues d’auteur, de titre et de date de création dans chaque conteneur disposant d’une couche de métadonnées, puis j’ai vérifié ce qui ressortait.
| Conteneur | author → dc:creator | title → dc:title | created → dcterms:created |
|---|---|---|---|
HTML (<meta name=author>, <title>) | ✅ | ✅ | non intégré |
| DOCX (propriétés de base) | ✅ | ✅ | ✅ exact 2021-03-15T09:30:00Z |
| PDF (dictionnaire d’infos) | ✅ | ✅ | présent, mais c’était l’horodatage du générateur — non noté |
ODT (meta.xml) | ✅ | ✅ | ✅ exact 2021-03-15T09:30:00Z |
| TXT / MD / CSV / RTF / XML | aucune couche de métadonnées | — | — |
L’auteur et le titre ont été récupérés sur 4 conteneurs dotés de métadonnées sur 4, et — c’est la partie intéressante — ils sont normalisés. Un <meta name="author"> HTML, une propriété de base DOCX, une entrée /Author d’un PDF et un élément dc:creator d’un ODT arrivent tous sous la même clé dc:creator. Tu écris un seul consommateur, pas quatre.
created est la petite instabilité honnête. DOCX et ODT ont renvoyé mon horodatage exact 2021 intégré. Le PDF a bien renvoyé une date de création, mais c’était celle estampillée par ma bibliothèque de génération au moment de la création, pas la valeur que j’avais voulu intégrer — je la compte donc comme présente, pas comme récupérée. Et les formats sans couche de métadonnées n’ont rien renvoyé, ce qui est la bonne réponse. Tika n’invente pas un auteur à partir du corps du texte.
Le casser exprès, et le réflexe de triage qui en découle
Quatre entrées hostiles. Un fichier de zéro octet. Un PDF valide dont le corps a été coupé. Un ZIP DOCX tronqué. Et un fichier UTF-8 contenant des caractères multioctets, sans BOM ni déclaration d’encodage. Ce sont des formes de fixtures locales, pas des seuils Tika.
Le banc de test sous-jacent, les fixtures générées, le JSON brut, le checksum du JAR et le manifeste d’environnement ne sont pas liés publiquement ici, donc un lecteur extérieur ne peut pas reproduire de manière indépendante les dénominateurs exacts. Il faut donc considérer les tableaux comme des observations rapportées, et non comme des preuves vérifiables par un tiers.
| Entrée | --text / --json | Exception renvoyée | --detect |
|---|---|---|---|
| Fichier de 0 octet | sortie 1, stdout vide | ZeroByteFileException: InputStream must have > 0 bytes | sortie 0 → text/plain avec nom de fichier, application/octet-stream depuis le flux |
| PDF tronqué | sortie 1, stdout vide | TikaException: TIKA-198: Illegal IOException from PDFParser | sortie 0 → application/pdf |
| DOCX tronqué | sortie 1, stdout vide | erreur fatale POI : "XML document structures must start and end within the same entity" | sortie 0 → type OOXML |
| UTF-8, sans BOM, sans déclaration | sortie 0 | rien | sortie 0 → text/plain, charset UTF-8 |
L’extraction échoue bruyamment, et ces échecs partagent la même forme externe. Le fichier de 0 octet, le PDF tronqué et le DOCX tronqué ont chacun produit une exception, un code de sortie 1 et un stdout vide. La CLI n’absorbe pas l’échec pour en faire une jolie réponse vide. C’est sûr du point de vue du processus dans ces cas — pas de blocage, pas de segfault — mais l’appelant doit vérifier le code de sortie et stderr, et pas seulement une chaîne vide.
La détection est découplée de l’analyse. Sur les deux binaires tronqués, --detect a renvoyé un code 0 avec le type attendu à partir du contenu de tête intact ; ensuite, le parseur a échoué sur le corps cassé. Un pipeline peut donc utiliser la détection comme signal de triage séparé, avant ou après une analyse échouée. Savoir s’il faut détecter d’abord par défaut dépend du mode de déploiement : ce test n’a pas comparé detect-first à parse-only, et deux nouveaux JVM CLI peuvent être un mauvais compromis à grande échelle.
La détection d’encodage fonctionne. Le fichier UTF-8 sans BOM ni déclaration a été décodé en UTF-8 et 日本語テスト est passé intact. Petite nuance pour ceux qui lisent les dictionnaires de métadonnées : mes fixtures purement ASCII remontent charset=ISO-8859-1, ce qui est indiscernable d’UTF-8 sur des octets ASCII. Ce n’est pas une erreur, c’est une égalité.
Tika à côté de unstructured : mêmes types de fichiers, mais pas le même travail
Les deux ont été testés dans la même session de recherche, mais il s’agit ici d’une typologie de contrats de sortie, pas d’un benchmark symétrique. Les outils ont été évalués sur des résultats différents.
Revue connexe : Revue de Unstructured.
| Apache Tika | unstructured | |
|---|---|---|
| Ce que j’ai mesuré | fidélité du contenu : quelque chose a-t-il été perdu ? | fidélité de la classification des éléments : chaque bloc a-t-il reçu le bon type ? |
| Résultat | tous les marqueurs injectés étaient présents sur les quatorze rendus | dans le test de classification séparé, un tableau en texte brut a donné un rappel Table de 0,000, et un titre contenant un verbe a été classé comme texte narratif |
| Éléments typés renvoyés | aucun — aucune structure n’est revenue non plus | Title, NarrativeText, ListItem, Table — précisément ce que Tika refuse de faire |
| OCR | bloqué sur ma machine, tesseract absent | bloqué sur ma machine, tesseract absent |
Sortie plate qui conserve les marqueurs contre éléments typés avec erreurs de classification observées. Choisis selon les besoins du consommateur aval. S’il s’agit d’un index de recherche ou d’une fenêtre de contexte LLM, du texte plat peut suffire. Si le système se base sur le type d’élément, le chemin --text de Tika ne peut pas fournir ce contrat.
Aucun des deux n’a de chiffres sur les documents scannés.
Avantages et inconvénients
Avantages
- La détection de type de contenu a ignoré les noms de fichier mensongers dans 20/20 conditions uniques sur les cinq fixtures détectables par contenu ; les exécutions de flux dupliquées concordaient aussi.
- Chaque marqueur injecté a survécu dans les 14 rendus de conteneurs, y compris les cellules de tableau et les éléments de liste étiquetés.
- Répétable sur trois relances locales : chaque conteneur a renvoyé un texte identique octet pour octet dans cet environnement.
- Métadonnées normalisées entre formats —
dc:creator/dc:title/dcterms:createdquelle que soit la source, récupérées sur 4/4 des conteneurs portant des métadonnées. - Vraiment sans dépendances externes pour les formats testés : couche texte PDF, DOCX, ODT, RTF, HTML, tous analysés depuis un seul JAR sans binaires externes.
- Fonctionne proprement sur OpenJDK 26 — pas de contrainte limitée aux versions LTS.
- La détection reste correcte (sortie 0) sur les binaires tronqués, ce qui fournit un signal de triage fiable quand l’analyse échoue.
- Licence Apache-2.0, mature, maintenu activement.
Inconvénients
- L’identité Markdown et CSV dépend entièrement de l’extension ; 10 cellules sans signature sur 18 sont tombées en
text/plaindès que le nom de fichier a disparu ou était faux. --textne renvoie pas de types d’éléments ; les tableaux sont aplatis en lignes jointes par tabulation et les marqueurs structurels de liste disparaissent.- L’extraction lève des exceptions non rattrapées sur les entrées vides ou corrompues ; les deux cas ont la même apparence depuis l’appel d’extraction seul.
- JAR de 67 Mo, plus un démarrage à froid du JVM à chaque invocation en mode CLI.
- L’OCR et les PDF scannés n’ont pas du tout été testés ici — tesseract et poppler étaient absents, donc aucune conclusion n’est formulée sur ce chemin.
- Tous les chiffres ici proviennent d’une vérité terrain synthétique, sur une machine et une version. La précision sur des corpus réels, les fichiers chiffrés, les documents imbriqués/récursifs et le débit à grande échelle n’ont pas été mesurés.
À qui ça convient, et à qui ça ne convient pas
Tika convient lorsque tes entrées sont des fichiers que tu possèdes déjà et que ta sortie doit être du texte plus des métadonnées qu’une machine peut indexer. Indexation de recherche, e-discovery, traitement d’archives, alimentation d’un corpus pour LLM, construction de la couche de validation de type de contenu d’un pipeline d’upload. Il est utile comme première étape de triage et de normalisation devant quelque chose de plus intelligent : détecter les types testés, extraire le texte plat, puis transmettre le tout avec des contrôles explicites sur le contenu que ton pipeline ne peut pas se permettre de perdre.
Passe ton chemin — ou plutôt, ne t’arrête pas à --text — si tu as besoin d’éléments typés, de tableaux reconstitués ou de mise en page documentaire. Écarte-le aussi si tes documents sont des scans, au moins tant que tu n’as pas installé tesseract et fait tes propres mesures, parce que je n’en ai aucune. Pour des volumes importants, benchmarke la bibliothèque ou le mode serveur par rapport à la CLI sur des documents représentatifs. Le coût de démarrage du processus était visible dans ce banc de test sur petits fichiers, mais le débit et la consommation de ressources n’ont pas été mesurés.
Le piège qui revient souvent : si ta couche de stockage supprime les noms de fichier et que tu traites du Markdown ou du CSV, ne compte pas sur Tika pour les distinguer du texte brut. Conserve le nom d’origine.
Alternatives, et où se situe Thunderbit
Commençons par un cadrage honnête, parce que la comparaison juste ici porte sur les entrées, pas sur la qualité. Tika est une boîte à outils libre, sous licence Apache-2.0, auto-hébergée, pour analyser des fichiers. Des fichiers déjà présents sur disque ou dans un bucket. Il ne récupère pas de pages, n’exécute pas JavaScript, ne gère pas l’anti-bot, et ne prétend pas le faire.
C’est précisément la frontière à partir de laquelle un service géré d’extraction web, y compris notre propre Thunderbit, peut entrer dans l’architecture : il récupère des pages vivantes, tandis que Tika analyse des fichiers déjà en ta possession. Cet article n’a pas comparé ces services à Tika, et ils ne sont pas interchangeables pour la même entrée.
La séparation propre est la suivante : Tika pour les documents déjà en ta possession, une API d’extraction gérée pour les pages web qu’il faut aller chercher. Beaucoup de pipelines utilisent les deux — crawl et extraction côté web, Tika sur les PDF et DOCX renvoyés ensuite.
Si tu compares plus largement l’écosystème open source, j’ai rédigé la comparaison complète des extracteurs open source, une revue des projets de scraping GitHub les plus utiles, une revue de Crawl4AI centrée sur l’approche Markdown pilotée par navigateur, ainsi qu’un tour d’horizon plus large des outils de scraping. Pour la voie no-code, il y a aussi un guide sur la manière de scraper un site avec l’IA.
Essayer Thunderbit pour l’extraction de données web
Verdict
Faut-il utiliser Apache Tika ? Oui, si ton travail consiste à transformer des fichiers hétérogènes en texte plat et en métadonnées normalisées, et que tu valides les champs ou les marqueurs que ton propre pipeline ne peut pas se permettre de perdre.
Le détecteur a été la partie la plus solide de ce test. Il a renvoyé le type attendu dans 20 conditions uniques sur 20 pour les cinq fixtures détectables par contenu, y compris les flux sans nom de fichier. Tous les marqueurs injectés ont survécu sur quatorze rendus, et la sortie s’est répétée à l’identique sur trois relances locales. Des preuves utiles. Ça reste des preuves synthétiques. Le fait d’avoir tout fait depuis un seul JAR sur ce JDK, sans binaires externes pour les chemins hors OCR testés, a gardé le déploiement agréablement banal.
Mais il faut le dimensionner correctement. Chaque tableau que tu lui donnes revient sous forme de lignes jointes par tabulations. Chaque marqueur structurel de liste disparaît. Markdown et CSV perdent leur identité dès que le nom de fichier s’en va. Les fichiers vides et corrompus produisent la même forme d’échec, et il faut l’appel detect séparé pour les distinguer. Quant à l’OCR, question qui intéresse beaucoup d’utilisateurs de Tika, je n’ai rien à offrir : je n’ai pas pu l’exécuter, et je ne vais pas estimer.
Dans ces limites, Tika fait un travail ingrat avec une fiabilité inhabituelle. Il lit les octets, pas l’étiquette sur la boîte. Ne lui demande simplement pas quelle forme avaient ces octets.
Essayer Thunderbit pour l’extraction de données web Get Started Free
FAQ
Apache Tika détecte-t-il correctement les types de fichiers si l’extension est fausse ?
Pour les cinq fixtures détectables par contenu testées ici, oui. PDF, DOCX, RTF, HTML et XML ont bien été résolus vers leur type MIME attendu dans les 20 conditions logiques uniques (30 exécutions brutes avec répétitions de flux), y compris avec des extensions trompeuses, sans extension, et avec des flux sans nom de fichier. Un PDF nommé .txt restait détecté comme application/pdf. Markdown et la petite fixture CSV dépendaient des informations de nom de fichier et retombaient en text/plain lorsqu’elles manquaient ou étaient erronées.
Tika préserve-t-il les tableaux et la structure des documents ?
Pas dans le mode --text testé ici. Les tableaux revenaient sous forme de lignes jointes par des tabulations, sans sémantique de cellule ou d’en-tête, et les marqueurs structurels de liste (un <li> HTML, un style DOCX List Bullet) disparaissaient. Tous les marqueurs injectés ont survécu sur les 14 rendus de conteneurs, mais cela ne prouve pas une fidélité complète du contenu, et --text ne fournit aucun typage d’éléments. Pour des éléments typés ou des tableaux reconstitués, teste un autre gestionnaire de sortie Tika ou utilise un autre outil à côté.
Apache Tika peut-il faire de l’OCR sur des PDF scannés ? Tika prend en charge l’OCR via Tesseract, mais je ne l’ai pas testé, et aucun résultat ici ne constitue une affirmation à ce sujet. Tesseract et poppler étaient absents de la machine de test, donc tous les chemins OCR et images scannées étaient bloqués avant exécution. Il n’y a aucun chiffre OCR dans ce test. Si l’OCR est ton cas d’usage, installe tesseract et fais tes propres benchmarks — considère cette partie de Tika comme non vérifiée ici.
Que fait Tika avec des fichiers vides ou corrompus ?
Il échoue bruyamment plutôt que silencieusement. Un fichier de 0 octet déclenche ZeroByteFileException; un PDF tronqué déclenche une TikaException provenant de PDFParser ; un DOCX tronqué déclenche une erreur XML de POI. Les trois se terminent avec le code 1 et un stdout vide, donc un fichier vide et un fichier corrompu sont indiscernables depuis le seul appel d’extraction. La détection, en revanche, reste robuste — --detect a renvoyé le code 0 avec le bon type sur les deux binaires tronqués, ce qui en fait une étape de triage fiable avant de lancer une analyse coûteuse.
Qu’est-ce que le test de Tika n’a pas couvert ? Quatre choses, explicitement. L’OCR et les images scannées (bloquées, non testées). La précision sur corpus réel — tous les résultats proviennent de fixtures synthétiques contrôlées avec jetons marqueurs injectés, ce qui mesure la fidélité par rapport à des étiquettes connues plutôt que l’exactitude sur des documents réels et désordonnés. Le coût en ressources, le débit et la mémoire maximale, que je n’ai pas mesurés. Et la longue traîne de la promesse des « mille types de fichiers » : j’ai testé neuf formats représentatifs sans dépendances externes, pas le catalogue complet. Tout ici correspond à Tika 3.3.2 sur OpenJDK 26.0.1, macOS arm64, sur une seule machine.


