Apache Tika, c’est la boîte à outils d’analyse de documents de l’Apache Software Foundation : tu lui donnes un fichier d’à peu près n’importe quel format, et il te renvoie du texte brut avec 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 embarquant lui-même les bibliothèques spécialisées — PDFBox pour les PDF, Apache POI pour les documents Office, jsoup pour le HTML, un lecteur ODF pour l’ODT — de sorte que tout tient dans un seul gros JAR, sans rien télécharger au moment de l’analyse. Dans un pipeline de données, c’est la première étape peu glamour : le composant placé devant un moteur de recherche, un ensemble de revue e-discovery ou un corpus pour LLM, qui transforme un tas hétérogène de fichiers en quelque chose d’uniforme. En vrai, ça fait deux tâches : déterminer ce qu’est un flux d’octets, puis en extraire le texte et les métadonnées.
C’est l’outil le moins prise de tête 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 très récent qui a planté d’autres outils Java sur la même machine le même après-midi. Cela dit, ce n’était pas l’argument de la fiche produit que je voulais vérifier ; la vraie question testable est plus serrée. Quand l’entrée te ment, Tika fait quoi, au juste ? 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 transport, puis j’ai attaqué l’ensemble avec de fausses extensions, des extensions manquantes, des noms de fichiers absents, des fichiers de zéro octet et des binaires partiellement écrits.
La détection, c’est là que le comportement devient intéressant. J’ai renommé un PDF en .txt et demandé à Tika ce que c’était ; il a répondu application/pdf. Ensuite j’ai supprimé complètement le nom de fichier, envoyé les octets bruts sur stdin, et j’ai obtenu la même réponse. Sur les cinq formats détectables par le contenu de mon jeu de tests, ça s’est vérifié dans 20 conditions logiques uniques : trois conditions de nom de fichier plus une condition sans nom de fichier par format. Le banc d’essai a exécuté trois fois le cas du flux sous des libellés différents, ce qui donne 30 exécutions brutes réussies, mais ces répétitions ne constituent pas des preuves indépendantes. PDF et RTF exposent des octets reconnaissables ; DOCX expose son conteneur ; HTML et XML peuvent être identifiés à partir du balisage ou du contenu racine. Mécanismes différents, 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 le régime des formats textuels, où Markdown retombe en text/plain dès que le nom de fichier est faux ou absent. Là, son identité dépendait entièrement de .md.
Deux limites à garder en tête pour tous les chiffres qui suivent. J’ai testé Apache Tika 3.3.2 — vérifié le 27 juillet 2026, c’était encore la dernière version stable ; la branche 4.0.0 n’existait alors qu’en versions alpha et bêta sur Maven Central. Le projet comptait environ 3,9 k étoiles GitHub au moment de cette vérification, et il est sous licence Apache-2.0, donc à peu près aussi peu contraignante que possible côté commercial. Et je n’ai pas testé l’OCR du tout. Pas une seule page scannée, pas un seul PDF composé uniquement d’images. Tesseract et poppler n’étaient pas installés sur la machine utilisée, donc tous les chemins OCR étaient bloqués avant même de démarrer. Il n’y a donc aucun chiffre OCR ici, tout simplement parce qu’il n’y en a pas.
Ce qu’est Tika, une fois qu’on arrête de lire le marketing sur la boîte
L’hypothèse classique, c’est qu’Apache Tika est un convertisseur de documents — tu lui donnes un DOCX, tu récupères un Markdown propre avec titres et tableaux intacts. Ce n’est pas ça, et plus vite c’est clair, mieux l’outil paraît.
Le chemin testé ici comporte trois étapes pertinentes : un détecteur de type de contenu, un dispatcher qui envoie les octets au bon parseur, puis le gestionnaire de sortie --text de la CLI, qui émet du texte plat avec les métadonnées disponibles séparément. Dans ce contrat de sortie, il n’y a pas d’objets Title, pas de ListItem, et pas de grille de tableau reconstruite. Tika propose aussi d’autres gestionnaires et API, y compris des sorties orientées XHTML/SAX ; je ne les ai pas testés. Toute conclusion structurelle ci-dessous concerne donc tika-app --text, et non l’idée que la boîte à outils n’offre nulle part de flux d’événements structuré.
Ça ressemble à une limite, et sous un angle, ça l’est. Mais ça veut aussi dire que Tika n’a rien à mal classer, et c’est justement 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 octets de signature, puis l’inspection de la racine XML, ensuite le motif du nom de fichier, puis tout type que tu as fourni toi-même (la documentation de détection de Tika l’explique). Ce n’est qu’une fois le type résolu que le dispatcher transmet les octets au parseur embarqué correspondant — PDFBox, POI, jsoup, TextAndCSVParser pour la famille texte.
Cette séparation entre détection puis analyse n’est pas un détail interne. C’est la raison pour laquelle un fichier trop abîmé pour être analysé peut quand même être typé correctement, ce qui devient l’astuce la plus pratique que Tika offre dès que les choses commencent à casser.
Installation : un seul JAR, une seule commande, et un JVM peu regardante
L’installation se résume à un téléchargement. tika-app-3.3.2.jar depuis Maven Central pèse environ 67 Mo — un gros JAR qui embarque chaque parseur — puis il suffit de lancer java -jar tika-app-3.3.2.jar --text file.pdf. Pas de fichier de configuration, pas de poids de modèle, pas d’étape post-installation, pas de chaîne brew install à dérouler.
L’histoire du JDK m’a surpris. J’ai exécuté l’ensemble sur OpenJDK 26.0.1, une version non-LTS très récente, et --version, --text, --metadata et --detect sont tous revenus avec un code de sortie 0, sans aucun avertissement de compatibilité. C’est utile de le signaler, parce que j’ai testé Apache Nutch sur la même machine, dans la même session, et son cycle d’exploration ne fonctionnait pas du tout sur JDK 26 — il lui faut au plus un LTS 21, à cause de la suppression de SecurityManager dans les JDK récents. Tika, lui, s’en fichait. Si tu évites les outils JVM à cause de ce genre de galère, Tika n’est pas là où ça coince.
Deux constats honnêtes côté installation. La CLI lance une nouvelle JVM à chaque invocation, donc le démarrage à froid est réel — 131 exécutions de mon banc d’essai ont pris environ une minute, surtout à cause de l’amorçage JVM. Si tu traites des fichiers en volume, mieux vaut utiliser la bibliothèque ou le mode serveur plutôt qu’une boucle shell autour du JAR. Et le discours « sans dépendance » a une limite nette : l’extraction de texte de la couche texte d’un PDF ne nécessite rien d’externe, mais l’OCR a besoin de tesseract et poppler. Les PDF avec couche texte, DOCX, ODT, RTF, HTML, XML, TXT, Markdown et CSV se sont tous analysés sur une machine où aucun des deux n’était installé. Les documents scannés, eux, n’auraient pas marché, et je ne vais pas faire semblant du 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 pour les PDF électroniques était complètement bloqué parce qu’importer son module PDF charge la pile d’inférence (torch et compagnie) dès l’import — avant même la sélection de stratégie, donc même la stratégie « fast » ne peut pas s’importer sans ça. Tika, lui, a extrait la couche texte du même PDF avec un simple java -jar.
Le test de l’extension mensongère : une détection MIME qui ignore le nom de fichier

Huit formats, chacun présenté avec une extension correcte, une extension volontairement fausse, ou sans extension, plus un flux d’octets sans nom de fichier sur stdin. Ça fait 32 conditions logiques uniques. Le banc d’essai d’origine a aussi exécuté les mêmes octets de flux une fois sous chaque libellé de nom de fichier, ce qui donne 48 exécutions brutes ; ces trois lignes de flux se ramènent à une seule condition, puisque stdin ne transporte aucun nom.
| Jeu de test | 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 à lire pour le motif.)
Les cinq formats détectables par le contenu — PDF, DOCX, RTF, HTML et XML — ont obtenu le vrai type dans 20 conditions uniques sur 20 (et 30 exécutions brutes sur 30, en comptant les répétitions de flux). Un PDF nommé report.txt restait un PDF. Un DOCX nommé photo.jpg restait un DOCX. Aucun n’avait besoin d’un nom de fichier. Ça ne veut pas dire que les cinq reposent tous sur des signatures d’octets fixes : les PDF et les RTF ont des en-têtes reconnaissables, le DOCX est un conteneur basé sur ZIP, et HTML/XML sont détectés à partir du balisage ou du contenu racine. Dans ces jeux de tests, l’extension mensongère n’a pas gagné.
Puis vient le régime des formats textuels. Markdown n’a été résolu en text/markdown que lorsque l’extension .md était présente et lisible. Renomme-le, supprime l’extension, ou envoie-le comme flux, et il est retombé en text/plain dans ce test. Le CSV a eu le même comportement sur cette grille volontairement réduite : text/csv n’est venu que du motif .csv. En comptant les conditions uniques, Markdown et CSV n’ont obtenu leur type spécifique que dans une condition sur quatre ; le texte brut était déjà text/plain, donc rien à partir duquel « retomber ». 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 fichier 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é. Tomber au type parent est un bien meilleur échec que d’affirmer avec assurance un faux type, et le fait que text/markdown soit un sous-type documenté de text/plain rend ce repli fondé plutôt qu’arbitraire.
Il y a un bémol spécifique au CSV. Tika dispose d’un détecteur statistique de CSV, et au moment de l’analyse — confirmé par TextAndCSVParser dans la chaîne X-TIKA:Parsed-By — ma petite grille de 2 colonnes sur 3 lignes a été résolue en text/plain plutôt qu’en text/csv. Ce n’est qu’une observation sur un jeu de tests volontairement minimal. Un CSV plus grand ou avec guillemets pourrait très bien déclencher le détecteur. Je ne dis pas que la détection par contenu du CSV est cassée ; je dis juste que, sur cette grille, c’est l’extension qui a produit text/csv.
Pourquoi ça compte dans un vrai pipeline d’upload
Le cas concret, c’est un routeur d’imports. Disons que tu acceptes des fichiers utilisateurs et que tu les orientes selon leur type : les PDF vers l’analyseur de factures, les tableurs vers l’importateur comptable, tout le reste vers un index texte. Si tu fais confiance à l’extension, quelqu’un qui envoie un PDF nommé notes.txt part dans la mauvaise branche — et ça, c’est le cas gentil ; la version hostile, c’est un fichier polyglotte avec une extension rassurante.
Pour les jeux de tests binaires et de balisage ici, Tika a routé selon le contenu même après disparition du nom de fichier, ce qui est utile quand un stockage objet ou un gestionnaire de corps HTTP l’a supprimé. Ce résultat ne couvre pas la longue traîne de Tika, les fichiers ambigus ou les polyglottes. Les jeux de tests textuels se sont comportés différemment : lorsque le pipeline supprimait les noms de fichiers, 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 plutôt que d’attendre de la détection de contenu qu’elle le reconstitue.
Le contenu injecté a survécu. --text a aplati la structure.
La fidélité est le deuxième axe, et là, la séparation est nette en deux. J’ai rendu un document canonique (titres, deux paragraphes, une liste à puces, une liste numérotée, un paragraphe de fin) en HTML, Markdown, texte brut, DOCX, PDF, RTF, ODT et XML, plus un document avec tableau en HTML, Markdown, texte, DOCX, CSV et XML. Quatorze rendus de transport. Chaque bloc porte un jeton unique — zztitle1, zzitem3, zztblcell_beta, etc. — donc « conservé » versus « perdu » se vérifie par recherche exacte de sous-chaîne, pas au pif.
Le rappel des jetons marqueurs est revenu à 1,000 sur les quatorze rendus. Aucun jeton injecté n’a disparu : chaque cellule de tableau, élément de liste et titre marqués était présent. Trois répétitions locales par transport après échauffement ont renvoyé une sortie --text identique au byte près. 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, des en-têtes, des notes de bas de page ou des objets incorporés. C’est un test de présence des blocs, pas une preuve d’exhaustivité de la fidélité du document.
La sortie en texte plat abandonne la majeure partie de la structure source.
Voici le document de tableau HTML tel qu’il ressort de --text :
Tool Throughput
zztblcell_alpha 120
zztblcell_beta 95
Des lignes séparées par des tabulations. La ligne d’en-tête n’est pas signalée comme telle. Il n’y a pas de grille, pas de bordures de cellules au-delà d’une tabulation, aucune façon de savoir qu’il s’agissait un jour d’un <table>. Le tableau DOCX est aplati de la même façon.
Les listes sont plus subtiles, et elles changent selon ce que contenait vraiment la source :
| Ce qu’était la puce dans la source | Formats | Ce que renvoie --text |
|---|---|---|
Un caractère littéral — ces rendus ont tous écrit - en texte réel | texte brut, Markdown, RTF, ODT, PDF | le - survit, parce que Tika transmet les caractères tels quels |
Une vraie structure — un <li> HTML, un style DOCX List Bullet | HTML, DOCX | le marqueur disparaît complètement et on n’obtient que le texte de l’élément : avec indentation par tabulation en HTML, ligne nue en DOCX |
Tika ne recrée jamais un marqueur qu’il n’a pas reçu en texte. Même contenu, rendu visuel différent.
Le cas Markdown illustre bien le point. Donne à Tika un fichier .md avec un tableau à barres, et les barres reviennent telles quelles, ce qui ressemble à une préservation de structure. Ce n’en est pas une. Tika l’a analysé 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, mais --text n’a pas préservé les éléments typés ni une grille de tableau reconstructible. Parler de 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 en 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 morceau de la chaîne, pas la chaîne entière. D’autres gestionnaires Tika peuvent exposer davantage de structure, mais ils étaient hors de cette série de tests.
Petit rappel standard sur tous les chiffres de fidélité ici : ils viennent de jeux de tests synthétiques contrôlés sur une seule machine, une seule version, un seul JDK. Ils montrent que les blocs marqués étaient présents dans la sortie. Ils n’établissent ni une préservation caractère par caractère ni une exactitude sur un corpus réel et sale.
Métadonnées : normalisées, et heureusement peu enclines à inventer

J’ai injecté des valeurs connues d’auteur, de titre et de date de création dans chaque format disposant d’une couche de métadonnées, puis j’ai vérifié ce qui revenait.
| Transport | author → dc:creator | title → dc:title | created → dcterms:created |
|---|---|---|---|
HTML (<meta name=author>, <title>) | ✅ | ✅ | non intégré |
| DOCX (propriétés principales) | ✅ | ✅ | ✅ exact 2021-03-15T09:30:00Z |
| PDF (dictionnaire d’informations) | ✅ | ✅ | 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 transporteurs sur 4 disposant de métadonnées — et, c’est le point intéressant, ils sont normalisés. Un <meta name="author"> HTML, une propriété principale DOCX, une entrée /Author dans un PDF et un élément dc:creator dans un ODT arrivent tous sous la même clé dc:creator. Tu écris un seul consommateur, pas quatre.
created est le petit point de friction honnête. DOCX et ODT ont renvoyé mon horodatage exact de 2021. Le PDF a renvoyé une date de création, mais c’était celle que ma bibliothèque génératrice a inscrite à la construction, pas la valeur que je voulais injecter — je la note donc comme présente, pas comme récupérée. Et les formats sans couche de métadonnées n’ont rien affiché du tout, ce qui est la bonne réponse. Tika n’invente pas un auteur à partir du corps du texte.
Le casser exprès, et l’astuce de triage qui en découle
Quatre entrées hostiles. Un fichier de zéro octet. Un en-tête PDF valide avec le corps tronqué. 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 jeu de tests locales, pas des seuils de Tika.
Le banc d’essai sous-jacent, les jeux générés, le JSON brut, le checksum du JAR et le manifeste d’environnement ne sont pas liés depuis ce brouillon. Un lecteur externe ne peut donc pas encore reproduire indépendamment les dénominateurs exacts. Considère les tableaux comme des observations rapportées ; la publication devrait joindre un lot stable avant d’utiliser ces chiffres comme preuve tierce.
| Entrée | --text / --json | Erreur levée | --detect |
|---|---|---|---|
| Fichier de 0 octet | exit 1, stdout vide | ZeroByteFileException: InputStream must have > 0 bytes | exit 0 → text/plain avec nom de fichier, application/octet-stream depuis le flux |
| PDF tronqué | exit 1, stdout vide | TikaException: TIKA-198: Illegal IOException from PDFParser | exit 0 → application/pdf |
| DOCX tronqué | exit 1, stdout vide | erreur XML fatale POI : "XML document structures must start and end within the same entity" | exit 0 → type OOXML |
| UTF-8, sans BOM, encodage non déclaré | exit 0 | rien | exit 0 → text/plain, charset UTF-8 |
L’extraction échoue bruyamment, et ces échecs ont la même forme extérieure. Le fichier de zéro 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 dans un résultat proprement vide. C’est sûr côté processus dans ces cas — pas de blocage, pas de segfault — mais l’appelant doit vérifier le statut de sortie et stderr, pas seulement l’absence de chaîne.
La détection est découplée de l’analyse. Sur les deux binaires tronqués, --detect est revenu avec un code 0 et le type attendu à partir du contenu initial intact ; puis le parseur a échoué sur le corps abîmé. Un pipeline peut donc utiliser la détection comme signal de triage séparé avant ou après un échec d’analyse. Que l’ordre détection d’abord soit le bon défaut dépend du mode de déploiement : ce test n’a pas comparé détection d’abord à analyse seule, et deux JVM CLI neuves peuvent être le mauvais compromis à volume.
La détection de charset fonctionne. Le fichier UTF-8 sans BOM ni déclaration a été décodé comme UTF-8 et 日本語テスト est passé intact. Petite nuance pour qui lit les dictionnaires de métadonnées : mes jeux ASCII purs rapportent charset=ISO-8859-1, ce qui est indiscernable de UTF-8 sur des octets ASCII. Ce n’est pas une erreur, c’est une égalité.
Tika face à unstructured : mêmes types de fichiers, travail différent
Les deux ont été évalués dans la même session de recherche, mais il s’agit ici d’une taxonomie de contrats de sortie, pas d’un benchmark symétrique. Les outils ont été notés sur des résultats différents.
Article lié : Test d’Unstructured.
| Apache Tika | unstructured | |
|---|---|---|
| Ce que j’ai mesuré | fidélité du contenu : quelque chose a-t-il été perdu ? | fidélité de classification des éléments : chaque bloc a-t-il obtenu le bon type ? |
| Résultat | tous les marqueurs injectés présents sur quatorze rendus | dans le test de classification séparé, un tableau en texte brut a obtenu 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 — exactement ce que Tika refuse de faire |
| OCR | bloqué sur ma machine, tesseract manquant | bloqué sur ma machine, tesseract manquant |
Sortie plate qui conserve les marqueurs contre éléments typés avec erreurs de classification observées. Choisis selon ce dont le consommateur en aval a besoin. Si c’est un index de recherche ou une fenêtre de contexte LLM, du texte plat peut suffire. Si ta logique dépend du type d’élément, la voie --text de Tika ne peut pas fournir ce contrat.
Aucun de nous n’a de chiffres sur les documents scannés.
Avantages et inconvénients
Avantages
- La détection du type de contenu a ignoré les noms de fichiers mensongers dans 20/20 conditions uniques sur les cinq jeux détectables par le contenu ; les exécutions de flux dupliquées concordaient aussi.
- Chaque marqueur injecté a survécu dans les 14 rendus de transport, y compris les cellules de tableau et les éléments de liste marqués.
- Répétable dans trois relances locales : chaque transport a renvoyé un texte identique au byte près dans cet environnement.
- Métadonnées normalisées entre formats —
dc:creator/dc:title/dcterms:createdquel que soit le format source, récupérées sur 4/4 des transporteurs disposant de métadonnées. - Vraiment sans dépendances pour les formats testés : couche texte PDF, DOCX, ODT, RTF, HTML se sont tous parsés depuis un seul JAR sans binaires externes.
- Fonctionne proprement sur OpenJDK 26 — aucune contrainte limitée aux versions LTS.
- La détection reste correcte (exit 0) sur les binaires tronqués, ce qui fournit un signal de triage fiable quand l’analyse échoue.
- Apache-2.0, mature, activement maintenu.
Inconvénients
- L’identité de Markdown et du CSV dépend entièrement de l’extension du fichier ; 10 des 18 cellules sans signature sont retombées en
text/plaindès que le nom de fichier a disparu ou était faux. --textne renvoie pas de types d’éléments ; les grilles de tableaux sont aplaties en lignes séparées par des tabulations et les marqueurs structurels de liste disparaissent.- L’extraction lève des exceptions non interceptées sur les entrées vides et corrompues ; les deux cas se ressemblent du point de vue de l’appel d’extraction seul.
- JAR de 67 Mo plus démarrage à froid d’une JVM à chaque invocation en mode CLI.
- L’OCR et les PDF scannés n’ont absolument pas été testés ici — tesseract et poppler étaient absents, donc aucune affirmation n’est faite sur ce chemin.
- Tous les chiffres ici viennent d’une vérité terrain synthétique sur une seule machine, une seule version. L’exactitude sur corpus réel, les fichiers chiffrés, les documents imbriqués/récursifs et le débit à grande échelle n’ont pas été mesurés.
Pour qui l’utiliser, et pour qui pas
Tika convient quand ton entrée est constituée de 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 du type de contenu d’un pipeline d’upload. C’est utile comme étape initiale de triage et de normalisation devant quelque chose de plus intelligent : détecter les types testés, extraire le texte brut, puis le transmettre avec des contrôles explicites sur ce que ton pipeline ne peut pas se permettre de perdre.
Évite-le — ou plutôt, ne t’arrête pas à --text — si tu as besoin d’éléments typés, de tableaux reconstruits ou de mise en page documentaire. Évite-le aussi si tes documents sont des scans, au moins tant que tu n’auras pas installé tesseract et refait tes propres mesures, parce que je n’en ai aucune. Pour des volumes importants, compare la bibliothèque ou le mode serveur à la CLI sur des documents représentatifs. Le démarrage du processus était visible dans ce banc d’essai sur petits fichiers, mais le débit et le coût en ressources n’ont pas été mesurés.
Le piège classique : si ta couche de stockage supprime les noms de fichiers et que tu traites du Markdown ou du CSV, ne compte pas sur Tika pour les distinguer du texte brut. Garde le nom d’origine.
Alternatives, et place de Thunderbit
Commençons par un cadrage honnête, parce que la bonne comparaison ici porte sur les entrées, pas sur la qualité. Tika est une boîte à outils gratuite, sous Apache-2.0, auto-hébergée, pour analyser des fichiers. Des fichiers que tu as déjà 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 où un service géré d’extraction web, y compris notre propre Thunderbit, peut entrer dans l’architecture : il récupère des pages en direct, 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 est simple : Tika pour les documents déjà chez toi, une API d’extraction gérée pour les pages web que tu dois aller chercher. Beaucoup de pipelines utilisent les deux — crawl et extraction côté web, Tika sur les pièces jointes PDF et DOCX qui reviennent.
Si tu compares plus largement dans l’écosystème open source, j’ai rédigé le comparatif complet des scrapers open source, une sélection des projets de scraping les plus utiles sur GitHub, un test pratique de Crawl4AI sur l’approche Markdown adossée au navigateur, et une vue d’ensemble des outils de scraping. Pour le no-code, il existe aussi un guide sur la façon 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 boulot consiste à transformer des fichiers hétérogènes en texte plat et en métadonnées normalisées, et si tu valides les champs ou marqueurs que ton pipeline ne peut pas se permettre de perdre.
Le détecteur a été le point fort de cette série. Il a renvoyé le type attendu dans 20 conditions uniques sur 20 pour les cinq jeux détectables par le 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 au byte près lors de trois relances locales. Des preuves utiles. Mais toujours des preuves synthétiques. Le fait de le faire depuis un seul JAR sur ce JDK, sans binaires externes pour les chemins non OCR testés, a rendu le déploiement agréablement banal.
Il faut quand même le dimensionner correctement. Chaque tableau que tu lui donnes revient sous forme de lignes séparées par des tabulations. Chaque marqueur structurel de liste disparaît. Markdown et CSV perdent leur identité dès que le nom de fichier disparaît. Les fichiers vides et corrompus déclenchent la même forme d’échec, et il faut l’appel detect séparé pour les distinguer. Et sur l’OCR, sujet qui intéresse le plus souvent les utilisateurs de Tika, je n’ai rien à offrir : je n’ai pas pu le lancer, et je ne vais pas inventer.
Dans ces limites, Tika fait un boulot peu glorieux avec une fiabilité inhabituelle. Il lit les octets, pas l’étiquette sur la boîte. Il ne faut juste pas lui demander la forme que ces octets avaient au départ.
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 jeux de tests détectables par le contenu évalués ici, oui. PDF, DOCX, RTF, HTML et XML ont été résolus dans 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 a toujours été détecté comme application/pdf. Markdown et le petit jeu CSV dépendaient des informations du nom de fichier et retombaient en text/plain quand 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 grilles de tableaux revenaient sous forme de lignes séparées par des tabulations, sans sémantique de cellule ni 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 transport, mais ça ne prouve pas une fidélité complète du contenu, et --text n’offre aucun typage des éléments. Pour des éléments typés ou des tableaux reconstruits, teste un autre gestionnaire de sortie Tika ou utilise un autre outil en complément.
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 n’en fait une affirmation. Tesseract et poppler étaient absents de mon environnement de test, donc tous les chemins OCR et images scannées ont été bloqués avant de s’exécuter. Il n’y a aucun chiffre OCR dans cette campagne. Si l’OCR est ton cas d’usage, installe tesseract et mesure-le toi-même — 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 renvoient exit 1 avec stdout vide, donc un fichier vide et un fichier corrompu sont indiscernables à partir de l’appel d’extraction seul. La détection, en revanche, reste robuste — --detect est revenu avec exit 0 et le bon type sur les deux binaires tronqués, ce qui en fait une étape de triage fiable avant de tenter l’analyse.
Qu’est-ce que les tests de Tika n’ont pas couvert ? Quatre choses, explicitement. L’OCR et les images scannées (bloqués, non testés). L’exactitude sur corpus réel — tous les résultats viennent de jeux de tests synthétiques contrôlés avec des jetons marqueurs injectés, ce qui mesure la fidélité par rapport à des étiquettes connues plutôt que l’exactitude sur de vrais documents bruité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 l’affirmation « plus d’un millier de types de fichiers » : j’ai testé neuf formats représentatifs, sans dépendance externe, et non le catalogue complet. Tout ce qui figure ici correspond à Tika 3.3.2 sur OpenJDK 26.0.1, macOS arm64, une seule machine.


