Test de Katana : `-jc` et `-headless` trouvent des points de terminaison différents, et aucune commande unique n’a permis de couvrir les deux

Dernière mise à jour le August 17, 2026
Test de Katana : `-jc` et `-headless` trouvent des points de terminaison différents, et aucune commande unique n’a permis de couvrir les deux
Résumé IA

Katana est le crawler de découverte de points de terminaison de ProjectDiscovery — un binaire Go sous licence MIT qui prend une cible en entrée et renvoie des URL et des endpoints pour l’outil suivant d’une chaîne. Il explore soit en mode HTTP sans navigateur, soit avec -headless, qui pilote Chromium. La documentation officielle présente le mode headless comme l’option offrant la meilleure couverture ; cet exemple montre pourquoi la nature des endpoints compte autant que leur quantité. J’ai monté un petit site comportant trois catégories d’endpoints volontairement différentes et j’ai mesuré, sur la version v1.6.1 avec -d 4, quels modes détectaient quoi.

Katana est le crawler de découverte de points de terminaison de ProjectDiscovery — un binaire Go sous licence MIT qui prend une cible en entrée et renvoie des URL et des endpoints pour l’outil suivant d’une chaîne. Il explore soit en mode HTTP sans navigateur, soit avec -headless, qui pilote Chromium. La documentation officielle présente le mode headless comme l’option offrant la meilleure couverture ; cet exemple montre pourquoi la nature des endpoints compte autant que leur quantité.

J’ai monté un petit site comportant trois catégories d’endpoints volontairement différentes et j’ai mesuré, sur la version v1.6.1 avec -d 4, quels modes détectaient quoi. Le HTML classique a été trouvé à 4/4 liens ainsi que toute la chaîne de trois sauts, dans les quatre configurations. La différence est apparue sur les endpoints exposés via du code JavaScript source par rapport à ceux révélés par des modifications du DOM à l’exécution.

Sur ce banc d’essai, le mode headless a trouvé la classe basée sur le DOM au runtime que les modes sans navigateur testés ont manquée, tandis que le mode standard avec -jc a trouvé les littéraux présents dans les fichiers JavaScript, que les deux exécutions headless ont ratés. Aucune ligne à la matrice de quatre commandes ne couvrait les deux classes. Le périmètre, la reprise et le comportement des fichiers connus constituaient les autres limites pratiques.

Ce qu’est réellement katana

Le crawler katana — projectdiscovery/katana sur GitHub — est écrit en Go et distribué sous licence MIT. J’ai testé la version v1.6.1 le 27 juillet 2026 ; la version compte, car les résultats de couverture et de fichiers connus ci-dessous sont des observations liées à une build précise.

Ici, l’étiquette de catégorie est plus importante que d’habitude. Un crawler de découverte de points de terminaison n’est pas un extracteur de données. Si vous cherchez un crawler Go qui vous renvoie des noms de produits et des prix sous forme de JSON structuré, katana n’est absolument pas le bon outil — il vous dira volontiers que /products/1138 existe, mais ne vous dira rien sur le contenu de la page. C’est intentionnel, et le juger sur l’extraction reviendrait à évaluer un détecteur de métaux sur sa capacité à estimer la valeur d’un bijou.

Son terrain naturel, c’est la reconnaissance en sécurité offensive et les pipelines d’automatisation : entrée STDIN, sortie d’URL, puis transmission à l’outil suivant. D’où la mise en garde évidente : toutes les mesures ici ont été réalisées sur un banc d’essai en local sur 127.0.0.1, que j’ai moi-même écrit. N’utilisez katana que sur des hôtes que vous possédez ou pour lesquels vous avez une autorisation écrite de test, et sur rien d’autre. Il ne s’agit pas de contourner des défenses, mais d’évaluer l’étendue des endpoints qu’une commande donnée énumère réellement.

Les trois modes, et ce que chacun peut voir

Le mode standard utilise un client HTTP en Go. Il récupère les pages, analyse le HTML, suit les liens href, et ne lance jamais de navigateur. Rapide, léger, mais aveugle à tout ce qui n’existe qu’après l’exécution de JavaScript.

-jc (-js-crawl) ajoute un analyseur JavaScript à cette voie sans navigateur. Il télécharge les fichiers .js liés et extrait du code les chaînes ressemblant à des URL. Aucune exécution, juste de la lecture. Il existe aussi -jsl (jsluice), présenté dans le README comme un analyseur plus lourd et plus gourmand en mémoire — je ne l’ai pas testé, donc je ne peux rien dire sur son impact sur la couverture.

System diagram: Scope Is Applied in Layers

-headless pilote Chromium et exécute les scripts de la page. Sur ce banc d’essai, c’était le seul mode Katana testé à récupérer le chemin assemblé à partir de fragments puis injecté dans le DOM au runtime. Ce résultat ne permet pas d’affirmer ce que chaque parseur, ou un futur mode Katana, pourrait récupérer.

Il y a aussi le modèle de périmètre, et c’est la partie que j’intégrerais avant de taper quoi que ce soit en production.

FlagCe qu’il contrôleValeurs / défaut
-fs (field scope)quels hôtes sont inclusdn, rdn, fqdn, ou une regex personnalisée — défaut sur rdn
-cs et -cosregex d’URL qui filtrent à l’intérieur de ce périmètre
-kffichiers connus : robots.txt et sitemap.xmlle README indique qu’une profondeur minimale de 3 est requise
-dprofondeur3 par défaut
-resumereprend un crawl interrompu

L’ordre n’est pas décoratif : il détermine si une regex d’hôte élargit l’exploration ou la vide silencieusement.

Installation : un binaire, une astérisque

Trois façons de l’installer, et une seule exige une chaîne d’outils :

Mode d’installationPrérequis
Depuis les sources : go install github.com/projectdiscovery/katana/cmd/katana@latestGo 1.25 ou plus récent est la version requise annoncée
Binaires précompilés sur la page des releasesaucune chaîne d’outils
Image Dockeraucune chaîne d’outils

Le mien s’est installé dans ~/go/bin/katana et affichait Current version: v1.6.1 à chaque exécution. Jusque-là, le scénario Go classique et agréable : un seul fichier, pas d’exécution au runtime.

L’astérisque concerne le headless, où le navigateur est une dépendance distincte du binaire :

Où s’exécute -headlessCe qu’il faut
Ma machinekatana a détecté automatiquement un Chromium déjà installé ; je n’ai pas relevé la version du navigateur ni fourni de chemin explicite
Un serveur nu, selon les instructions Ubuntu du projetapt install google-chrome-stable avant que headless ne fasse quoi que ce soit
La voie Dockerexécution headless avec -system-chrome

Sur un serveur nu, cette simplicité disparaît. Il faut budgéter un navigateur, pas seulement un binaire, dès que -headless entre dans la commande.

Un point plus discret mais utile si vous l’exécutez en CI : katana effectue au démarrage une vérification de version auprès de GitHub. -duc la désactive. Sur un ordinateur portable, c’est du bruit ; sur un exécuteur isolé du réseau ou soumis à des limites de requêtes, c’est un aller-retour réseau par exécution que vous n’avez pas demandé. Mes mesures de temps utilisent -duc afin que les chiffres reflètent le crawl, et non une vérification vers l’extérieur.

Méthode de test

Trois catégories d’endpoints, choisies précisément parce qu’elles séparent les modes. Tout se trouve sur un serveur de fixture local, et la vérité terrain a été notée avant tout crawl, afin que le rappel soit mesuré par rapport à un ensemble fixe et non à ce que katana a décidé d’afficher.

  • Classe A — HTML simple. /page/a, /page/b, /page/c, plus une chaîne de trois sauts /depth/1 → /depth/2 → /depth/3. Tout crawler devrait les récupérer.
  • Classe B — littéraux dans un fichier JavaScript. /api/js-endpoint-7 et /api/js-endpoint-8 n’existent que comme chaînes de caractères dans un /static/app.js lié. Lisibles sans navigateur, si quelque chose prend la peine de lire le JS.
  • Classe C — uniquement au runtime dans le DOM. Un chemin assemblé à l’exécution à partir de fragments ('endpoint' + (6 * 7)) et injecté dans le DOM par un script. La chaîne /runtime-only/endpoint42 n’apparaît jamais de façon continue dans les octets envoyés par le serveur — ni dans le HTML, ni dans le source JS. Seule l’exécution permet de la voir.

S’y ajoutent un robots.txt, un sitemap.xml contenant deux endpoints <loc> n’apparaissant nulle part ailleurs, une route renvoyant 500, un lien mort, et un lien hors périmètre pointant vers un second serveur sur un autre hostname.

L’instrument compte autant que la fixture : le serveur enregistre ce qui a réellement été récupéré, donc les affirmations sur le scope et la reprise reposent sur la vérité des requêtes, pas sur la sortie standard de katana. Les exécutions brutes sont archivées dans le dépôt de benchmark si vous voulez vérifier mes calculs.

Le split de couverture que personne ne quantifie

Measured results chart: Endpoint coverage by Katana mode

La matrice, par mode et par classe d’endpoints, avec -d 4 :

ModeLiens HTML (A)Chaîne de profondeur (A)Littéraux JS (B)Runtime-DOM (C)
standard4/43/30/2non trouvé
standard -jc4/43/32/2non trouvé
-headless4/43/30/2trouvé
-headless -jc4/43/30/2trouvé

Lisez les deux dernières colonnes ensemble, et le problème saute aux yeux. La classe B n’a été trouvée que par une seule configuration : le mode standard avec -jc. La classe C n’a été trouvée que par deux : les deux exécutions headless. Il n’existe aucune ligne où les deux colonnes sont cochées. La matrice complète se trouve dans discovery-summary.json, où le champ calculé headless_jc_covers_both vaut false.

La conséquence pratique, c’est que « utilisez simplement headless pour avoir une meilleure couverture » était une formule incomplète pour ce test. Le mode headless n’a pas ajouté la classe B au résultat standard ; il a récupéré la classe C tout en ratant la classe B. Pour couvrir toutes les classes plantées dans cette fixture, il a fallu deux crawls puis une fusion :

katana -u https://target.example -jc -d 4 -silent -o pass-jc.txt
katana -u https://target.example -headless -d 4 -silent -o pass-headless.txt
sort -u pass-jc.txt pass-headless.txt > endpoints.txt

La ligne -headless -jc est celle sur laquelle j’aimerais le plus avoir une réponse en amont. Ajouter l’analyseur JavaScript à l’exécution headless n’a rien apporté — toujours 0/2 sur la classe B, dans chaque run, y compris une reproduction fraîche. Je rapporte le comportement, sans prétendre avoir isolé le mécanisme ; je n’ai pas instrumenté les entrailles de katana pour comprendre pourquoi la voie navigateur cesse de contribuer aux littéraux de fichiers JS. Il faut le considérer comme une observation reproductible et un bon sujet de ticket GitHub, pas comme un diagnostic. (À noter aussi : la combinaison -hl -jc s’est terminée correctement avec un code retour 0 sur v1.6.1 sous macOS ARM, ce qui n’a pas toujours été vrai historiquement.)

La documentation officielle décrit le mode headless comme offrant une meilleure couverture, et c’était vrai ici pour la classe rendue au runtime. Les consignes vérifiées n’explicitaient pas cette séparation entre littéraux source et DOM runtime, donc il faut considérer la matrice comme une raison de tester les deux voies sur vos propres classes d’endpoints, pas comme une taxonomie universelle.

Ce que le headless coûte en temps réel

Trois exécutions consécutives par mode sur une machine autrement inactive :

Modep50min–maxmoyenne
standard13.08 s13.07–13.17 s13.11 s
-headless66.82 s66.78–67.68 s67.09 s

C’est un ratio de 5,1x avec des plages qui ne se chevauchent même pas de près — ma pire exécution standard (13.17 s) restait encore plus rapide que ma meilleure exécution headless (66.78 s) de plus de 53 secondes (cost-summary.json). Ce n’est pas du bruit de mesure.

Une nuance sur ces 13 secondes : ma fixture inclut volontairement une route en 500 et un lien mort, et le mode standard attend le délai de retry par défaut -timeout 10 sur les deux. Je n’ai pas ajusté le timeout pour flatter le mode rapide, ce qui signifie qu’un mode standard optimisé élargirait probablement l’écart plutôt que de le réduire.

Ce ratio est un signal de capacité locale, pas une prévision de production. Les cibles réelles varient en latence, en erreurs, en exécution de scripts et en planification, alors que cette fixture inclut une traîne de timeout par défaut. Utilisez l’écart mesuré de 5,1x pour décider si le headless mérite un budget séparé et un sous-ensemble de cibles, puis validez ce plan sur des hôtes représentatifs et autorisés.

Le périmètre tient, mais un flag n’a discrètement rien fait

Le test de scope utilisait deux serveurs : le principal sur 127.0.0.1, et un second accessible via localhost sur un autre port, servant un chemin qui n’existe que là-bas. Donc un hit sur ce chemin prouve que l’hôte hors périmètre a bien été récupéré, et pas simplement imprimé.

ConfigurationHôte hors périmètre récupéré ?Hits sur le second serveur
par défaut (-fs rdn)non0
-fs fqdnnon0
-cs localhostnon0
`-fs '(127.0.0.1localhost)'`oui

La discipline du scope est une bonne nouvelle : par défaut, katana est resté chez lui, et il a fallu un acte explicite pour élargir. C’est le bon comportement par défaut pour un outil qu’on pointe sur l’infrastructure d’autrui.

La ligne intéressante est -cs localhost. Elle n’a pas élargi l’exploration au second hôte — et elle a aussi produit zéro URL. Comme -cs filtre à l’intérieur du field scope, et que le field scope était encore celui de l’hôte principal, la regex n’a rien fait correspondre et le crawl a renvoyé un ensemble vide au lieu d’une erreur. Si vous avez déjà écrit une regex de scope en nommant un hôte que vous vouliez inclure puis regardé un fichier de sortie vide, voilà le mécanisme (scope-summary.json). Pour ajouter un hôte, utilisez -fs. Pour restreindre à l’intérieur d’hôtes déjà inclus, utilisez -cs/-cos.

La reprise est plus grossière que ne le laisse penser le flag

Le README décrit le flag comme -resume string resume scan using resume.cfg, ce qui fait penser à un fichier déposé dans le répertoire courant. Ce n’est pas le cas. Sur ma machine, le point de contrôle a été écrit dans ~/.config/katana/resume-<xid>.cfg — mesuré, pas lu dans la documentation, car celle-ci n’indique pas de chemin.

Le plus surprenant est ce qu’il contient. Le fichier ne renfermait qu’une map InFlightUrls avec une seule chose : l’URL de départ. Ni l’ensemble des URL visitées, ni la frontière. Voilà donc ce qui s’est passé lorsque j’ai interrompu un crawl avec SIGINT après trois secondes puis relancé la reprise :

ExécutionChemins distincts
Crawl complet de référence11
Récupérés avant l’interruption10
Re-récupérés par la repriseles 11, y compris les 10 déjà terminés

La reprise a bien atteint le même ensemble final d’endpoints, donc rien n’est cassé. Mais la granularité du checkpoint est par seed d’entrée, pas par URL — le filtre de déduplication en mémoire n’est jamais persisté, donc reprendre un crawl à seed unique le refait depuis le début (resume-summary.json). Si vous donnez à katana une liste de 500 hôtes, la reprise devrait vous épargner ceux qui ont complètement fini ; ce comportement multi-seed découle de la manière dont l’état est stocké, mais je n’ai mesuré que le cas à seed unique. Si vous êtes au milieu d’un très grand site, la reprise vous apporte la correction, pas le temps.

Les fichiers connus : demandés, puis abandonnés

System diagram: Known files: requested, then dropped

-kf all -d 3 a bien demandé les deux fichiers — robots.txt et sitemap.xml sont apparus dans le journal d’accès du serveur — puis n’a récupéré 0 des 2 endpoints listés dans les balises <loc> de ce sitemap. Rappel 0,0.

Avant de conclure à une limite, j’ai essayé de voir si l’erreur venait de ma configuration. Chaque variante a renvoyé le même résultat :

Variante testéeEndpoints <loc> du sitemap récupérés
-kf all0/2, rappel 0,0
-kf sitemapxml0/2, rappel 0,0
-kf robotstxt0/2, rappel 0,0
profondeur 30/2, rappel 0,0
profondeur 40/2, rappel 0,0
profondeur 50/2, rappel 0,0
avec -jc ajouté0/2, rappel 0,0
amorcé directement sur /sitemap.xml0/2, rappel 0,0

L’exigence documentée — utiliser -kf, aller au moins trois niveaux de profondeur — était satisfaite à chaque fois. Il ne s’agit donc pas d’un simple flag manquant.

La décision utile vient d’abord : sur cette fixture à littéral IP, n’assumez pas que demander les fichiers connus implique que leurs URL <loc> ont été intégrées au crawl. Vérifiez le rappel, ou extrayez ces URL vous-même et utilisez-les comme graines.

Le chemin de code v1.6.1 concorde avec cette observation, mais je ne l’ai pas instrumenté pendant l’exécution. Dans sitemapxml.go à v1.6.1, NewNavigationRequestURLFromResponse construit des requêtes de navigation <loc> à partir d’une réponse sans RootHostname renseigné. La requête arrive ensuite à ValidateScope; dans scope.go à v1.6.1, la branche pour les hôtes à littéral IP compare l’hôte de l’URL à cette racine vide et peut la rejeter. La commande personnalisée -fs '(127.0.0.1|localhost)' a emprunté une autre branche de scope dans un test séparé, c’est donc un sauvetage prédit par le code source, pas un contournement mesuré de -kf. Une tentative de confirmation a été bloquée par des erreurs de connexion intermittentes dans le client des fichiers connus sur cet hôte ; le résultat rapporté reste donc 0/2.

En production, tant que personne ne confirme ce flag, je ferais ceci : récupérer le sitemap moi-même, extraire les URL <loc>, puis les fournir à katana comme liste de graines. Deux lignes de shell, sans validation de scope.

Un point s’est comporté exactement comme annoncé et mérite une phrase : la route en 500 et le lien mort ont bien été récupérés, journalisés puis ignorés. Toutes les exécutions sans navigateur se sont terminées avec un code retour 0. Un crawler qui s’arrête au premier mauvais retour est inutilisable en mode non supervisé, et katana ne fait pas cela.

Vérification de couverture spécifique à la cible avant déploiement

La matrice de la fixture est surtout utile comme modèle pour tester vos propres cibles autorisées. Définissez les catégories d’endpoints avant d’exécuter Katana : liens simples, littéraux dans des scripts liés, routes créées uniquement après exécution, et entrées de fichiers connus constituent quatre catégories de départ raisonnables. Conservez un petit échantillon de vérité terrain pour chaque catégorie. Sans cette liste préalable, un stdout plus volumineux peut donner l’illusion d’une meilleure couverture alors qu’une classe entière a disparu.

Exécutez d’abord séparément les voies sans navigateur et headless. Sauvegardez les commandes exactes, la version de Katana, la version du navigateur, les codes retour et les sorties. Normalisez et comparez les ensembles d’endpoints au lieu de vous fier au nombre de lignes. Si -jc en mode standard n’apporte rien d’unique sur votre échantillon, une politique headless seule peut suffire ; si les ensembles divergent comme ici, gardez les deux passes séparées et fusionnez après collecte. Ajouter les deux flags dans une seule commande ne doit pas être considéré comme équivalent à l’union tant qu’un diff propre à la cible ne l’a pas prouvé.

Validez le scope avec des preuves extérieures à la sortie de Katana. Placez une URL leurre sur un hôte censé rester exclu et inspectez le journal de requêtes de ce serveur. Testez aussi un second hôte voulu si le crawl est censé s’élargir. L’exécution -cs localhost ici a produit une sortie vide parce que le filtrage de content-scope n’a pas élargi le field scope ; l’invocation personnalisée -fs '(127.0.0.1|localhost)' a, elle, bien contacté le second serveur. Conserver l’expression régulière exacte est important, car un changement d’un seul caractère peut modifier la regex elle-même, pas seulement sa présentation.

Testez l’interruption et les fichiers connus séparément du rappel de découverte. Pour la reprise, interrompez une graine représentative après plusieurs pages, enregistrez le chemin du checkpoint généré et comptez combien d’URL déjà complétées sont récupérées à nouveau. Pour -kf, confirmez à la fois que robots/sitemap ont été demandés et que les URL <loc> plantées ont effectivement été mises en file d’attente. Ce sont des assertions différentes. Dans cette fixture, les fichiers ont bien été récupérés alors que les deux endpoints du sitemap étaient absents, donc les logs serveur et la sortie endpoints étaient tous deux nécessaires pour voir la limite.

Enfin, établissez un coût de référence local avec des exécutions séquentielles sur une machine autrement inactive, puis recommencez sur des hôtes représentatifs. Conservez le minimum, le maximum et la médiane plutôt qu’un simple multiplicateur. Le facteur 5,1x ici inclut le comportement de cette fixture face aux erreurs et aux timeouts ; il vous dit que le headless mérite son propre budget, pas combien de temps prendra un inventaire en production.

Avantages et inconvénients

Avantages :

  • Rappel parfait sur le HTML classique dans tous les modes — 4/4 liens et toute la chaîne de profondeur 3/3, sans configuration particulière.
  • -jc fonctionne réellement sans navigateur : 2/2 endpoints récupérés à partir de chaînes dans un fichier JS lié, sans coût de navigateur.
  • -headless est le seul à avoir trouvé un endpoint assemblé au runtime — une classe invisible par construction à l’analyse du source.
  • Les défauts de scope sont prudents. L’hôte hors périmètre n’a jamais été récupéré avec les paramètres par défaut, -fs fqdn ou -cs.
  • Un seul binaire Go, licence MIT, builds précompilés et image Docker, I/O adaptée aux pipelines.
  • Robuste en cas d’échec : les 500 et les liens morts n’arrêtent pas le crawl.

Inconvénients :

  • Aucune exécution unique n’a couvert à la fois les endpoints issus de fichiers JS et ceux du DOM runtime. Une couverture complète exige deux passes et une fusion.
  • -jc n’a rien apporté sous -headless — 0/2 sur la classe B dans chaque exécution headless.
  • Le headless coûte 5,1x en temps réel (p50 de 66,82 s contre 13,08 s, plages non chevauchantes).
  • -resume recrawle les pages déjà complétées dans une seed. Il restaure l’ensemble des endpoints, pas le temps déjà passé.
  • Les fichiers connus ont demandé robots.txt et sitemap.xml mais n’ont récupéré 0/2 endpoints <loc> du sitemap contre une cible IP.
  • Le headless nécessite discrètement un Chromium installé sur la machine ; l’histoire du « seul binaire » s’arrête au navigateur.
  • Découverte uniquement. Pas d’extraction structurée, pas de conversion de contenu, pas de schéma de champs.

Non testés, et donc hors de portée de tous ces chiffres : -jsluice, un test de coupure de profondeur dédié à -d 1/-d 2, la reprise multi-seed, le remplissage automatique de formulaires, et tout site de production réellement lourd en JavaScript ou protégé. Tous les chiffres proviennent d’une seule machine (macOS arm64) sur une fixture locale.

À qui il s’adresse, et qui devrait passer son tour

Si votre travail consiste à produire un inventaire d’endpoints pour une infrastructure que vous êtes autorisé à toucher, katana a la bonne forme de pipeline : plomberie STDIN/STDOUT, binaire distribuable, modes sans navigateur et avec navigateur. La fusion en deux passes était nécessaire pour les classes plantées dans cette fixture ; savoir si vos cibles ont besoin des deux passes est quelque chose à établir à partir de pages représentatives.

Passez votre chemin si vous voulez des données plutôt que des adresses. Katana ne vous donnera jamais un tableau de produits ; il vous donne les URL où ces produits peuvent se trouver, et un autre outil fait l’extraction. Passez aussi si vous avez besoin qu’une seule commande soit complète — la fusion en deux passes est très bien dans un pipeline, mais pénible au prompt. Et si votre énumération repose sur les endpoints <loc> d’un sitemap alors que vous ciblez des IP, vérifiez ce que vous recevez réellement avant de faire confiance à la sortie, car sur ma fixture ce chemin ne renvoyait rien.

Alternatives et frontière avec l’extraction

Katana est gratuit, sous licence MIT et auto-hébergé. Il garde la découverte, le choix du mode, le déploiement du navigateur et la fusion des résultats de votre côté de la frontière.

Dans l’open source, les comparaisons utiles se font par tâche plutôt que par langage. Colly est l’autre option en Go, mais c’est une bibliothèque que vous compilez avec vos propres callbacks et elle ne rend pas JavaScript du tout. Crawl4AI exécute un vrai navigateur et produit du Markdown pour des pipelines LLM, ce qui est un tout autre type de sortie. Si vous comparez plusieurs outils à la fois, notre tour d’horizon des extracteurs open source présente les catégories côte à côte.

Divulgation : Thunderbit est le produit de l’éditeur et n’a pas été testé dans cette fixture Katana. Il se situe en aval, dans la catégorie de l’extraction gérée, en transformant les pages en texte ou en enregistrements structurés plutôt qu’en énumérant la surface d’endpoints d’une cible autorisée. Un workflow peut utiliser les deux catégories, mais cet article fournit uniquement des preuves sur le comportement de découverte de Katana.

Essayez Thunderbit pour l’extraction de données web

Verdict

Utilisez katana lorsque le livrable est une liste d’endpoints pour des cibles que vous êtes autorisé à explorer et que vous pouvez valider la couverture des modes sur ces cibles. Sur cette fixture, le mode standard -jc a récupéré les littéraux JavaScript plantés, tandis que le mode headless a récupéré l’endpoint injecté dans le DOM runtime ; les modes sans navigateur testés n’ont pas retrouvé ce chemin runtime. Le scope par défaut a également empêché la récupération du second hôte, et les exécutions sans navigateur ont continué après le 500 et le lien mort.

Les réserves sont opérationnelles : une fusion en deux passes peut être nécessaire pour des classes d’endpoints mixtes, le headless a pris environ cinq fois plus de temps localement, la reprise sur une seule seed a refait les chemins déjà complétés, et le rappel des fichiers connus était de 0/2 contre la cible IP. Ce sont des résultats de la fixture v1.6.1, pas des garanties pour tous les sites. Ils suffisent à définir les vérifications qu’une évaluation en production devrait répéter.

Essayez Thunderbit pour l’extraction de données web Get Started Free

FAQ

Où katana enregistre-t-il son fichier de reprise, et la reprise saute-t-elle les pages déjà explorées ? Le point de contrôle a été enregistré dans ~/.config/katana/resume-<xid>.cfg, et non dans un resume.cfg du répertoire de travail comme le suggère l’aide du flag. Et non, il ne saute pas les pages terminées : le fichier ne stocke que les URL de graines en cours, donc une reprise sur une seule seed a récupéré à nouveau les 11 chemins de référence, y compris les 10 déjà terminés. On obtient le même ensemble final d’endpoints, mais pas le temps économisé.

Pourquoi -kf all a-t-il demandé mon sitemap.xml sans pour autant explorer les URL qu’il contient ? Sur une cible IP, c’est une limite de validation du scope, pas une erreur de flag. Le parseur de sitemap de Katana construit chaque requête <loc> sans faire suivre le hostname racine, puis la vérification du scope DNS pour les hôtes à littéral IP compare l’hôte de l’URL à cette racine vide, échoue et rejette l’URL. Le rappel est resté à 0 sur toutes les variations de flag, de profondeur et de seed que j’ai essayées. Une regex d’hôte personnalisée avec -fs suit une autre branche de validation et c’est la correction que le code source laisse prévoir — mais je n’ai pas pu la confirmer avec -kf sur ma machine, donc considérez-la comme non testée. Extraire vous-même les URL <loc> et les donner à katana comme graines est l’approche à laquelle je ferais confiance aujourd’hui.

Que dois-je conserver quand je rends compte d’un test de couverture Katana ? Enregistrez la version exacte de Katana et la commande, y compris l’expression -fs au caractère près ; définissez les catégories d’endpoints avant l’exécution ; gardez les logs de requêtes côté serveur en plus de stdout ; et séparez les comportements mesurés des hypothèses tirées du code source. Pour les exécutions headless, notez aussi la version du navigateur — ce test ne l’a pas fait, ce qui limite la reproductibilité.

Dois-je utiliser -jc, -headless, ou les deux ? Choisissez en fonction des catégories d’endpoints dont vous avez besoin. Dans cette fixture, le mode standard -jc a trouvé des littéraux stockés dans un fichier JavaScript, tandis que le mode headless a trouvé l’endpoint injecté dans le DOM runtime. Aucun des deux modes ne couvrait les deux classes à lui seul, donc une exécution en deux passes suivie d’une déduplication était le choix défendable pour des cibles mixtes.

Une URL en échec arrêtera-t-elle le crawl ? Non, pas dans ce test contrôlé. Katana a continué après une réponse 500 et un lien mort, et a tout de même renvoyé les autres chemins atteignables. Cela ne remplace pas la gestion d’erreurs en production : conservez les logs des requêtes en échec et définissez un taux d’échec acceptable afin qu’un crawl partiellement réussi ne soit pas pris pour une couverture complète.

Ke
Ke
CTO chez Thunderbit | Data Scientist senior et expert en ML Forte d’une expérience de près de dix ans en machine learning et en data science, Ke Shen est diplômé de Columbia University et ancien Data Scientist senior chez Walmart Labs. Grâce à une expertise approfondie, reconnue par ses pairs, en Python, R, Java et statistiques, il partage des analyses éprouvées sur le passage d’algorithmes d’IA complexes de la théorie à une architecture prête pour la production.
Topics
Outils d’extraction WebExtracteur Web IA
Table des matières
Thunderbit · Agent IA de données web

Extrayez des données de n'importe quelle page en 1 clic

Approuvé par plus de 250 000 utilisateurs
formule gratuite disponible
De la page web au tableur
Décris ce dont tu as besoin — l'agent IA de Thunderbit l'extrait et l'exporte vers Excel, Google Sheets, Airtable ou Notion. Gratuit pour commencer.
Chrome Store Rating
PRODUCT HUNT#1 Product of the Week