Reseña de Katana: `-jc` y `-headless` encuentran endpoints distintos, y ningún comando único logró abarcar ambos

Última actualización: August 19, 2026
Reseña de Katana: `-jc` y `-headless` encuentran endpoints distintos, y ningún comando único logró abarcar ambos
Resumen con IA

Katana es el crawler de ProjectDiscovery para descubrir endpoints: un binario en Go, con licencia MIT, que toma un objetivo y devuelve URLs y endpoints para que la siguiente herramienta de la cadena siga trabajando. Puede rastrear en modo HTTP sin navegador o con -headless, que usa Chromium. La documentación oficial presenta el modo headless como la opción con mayor cobertura; este caso de prueba muestra por qué el tipo de endpoint importa tanto como la cantidad. Monté un sitio pequeño con tres clases de endpoints, a propósito distintas entre sí, y medí cuál encontraba cada modo en la v1.6.1 con -d 4.

Katana es el rastreador de descubrimiento de endpoints de ProjectDiscovery: un binario en Go, con licencia MIT, que recibe un objetivo y devuelve URLs y endpoints para la siguiente herramienta de una cadena. Puede rastrear en modo HTTP sin navegador o con -headless, que usa Chromium. La guía oficial presenta el modo headless como la opción con mayor cobertura; este caso muestra por qué el tipo de endpoint importa tanto como la cantidad.

Monté un sitio pequeño con tres clases de endpoints claramente distintas y medí qué modo encontraba cada una en la versión v1.6.1 con -d 4. El HTML convencional llegó a 4/4 enlaces y a la cadena completa de tres saltos en las cuatro configuraciones. La diferencia apareció en los endpoints expuestos mediante código JavaScript frente a los cambios del DOM en tiempo de ejecución.

En este caso, headless encontró la clase de DOM en tiempo de ejecución que los modos sin navegador evaluados no detectaron, mientras que el modo estándar con -jc encontró literales dentro de archivos JavaScript que ambas ejecuciones headless pasaron por alto. Ninguna de las cuatro combinaciones cubrió ambas clases. El alcance, la reanudación y el comportamiento de archivos conocidos marcaron los otros límites prácticos.

Qué es realmente katana

El rastreador katana — projectdiscovery/katana en GitHub — está escrito en Go y tiene licencia MIT. Probé v1.6.1 el 27 de julio de 2026; la versión importa porque los resultados de cobertura y archivos conocidos que muestro abajo dependen de la build.

Aquí la categoría pesa más de lo habitual. Un rastreador de descubrimiento de endpoints no es una herramienta de extracción de campos. Si buscas un rastreador web en Go que te entregue nombres de productos y precios como JSON estructurado, katana está en el pasillo equivocado: te dirá encantado que /products/1138 existe, pero no dirá nada sobre lo que hay en esa página. Ese es precisamente su objetivo, y juzgarlo por extracción sería como evaluar un detector de metales por su capacidad de tasar joyas.

Su terreno natural es la inteligencia ofensiva y la automatización de pipelines: entra por STDIN, salen URLs, y lo encadenas con la siguiente herramienta. Eso trae la advertencia obvia: todas estas mediciones se hicieron sobre un entorno de pruebas en 127.0.0.1 que yo mismo construí. Usa katana únicamente en hosts que poseas o para los que tengas autorización escrita para probar, y en nada más. Aquí no se trata de evadir defensas ajenas; se trata de cuánta superficie de endpoints de un sitio enumera realmente un comando concreto.

Los tres modos y qué ve cada uno

El modo estándar es un cliente HTTP de Go. Descarga, analiza HTML, sigue hrefs y nunca inicia un navegador. Es rápido, barato y ciego a todo lo que solo existe después de ejecutar JavaScript.

-jc (-js-crawl) añade un parser de JavaScript a esa ruta sin navegador. Descarga los archivos .js enlazados y extrae del código literales con forma de URL. No ejecuta nada; solo lee. También existe -jsl (jsluice), descrito en el README como un parser más pesado y exigente en memoria; no lo probé, así que no puedo decir si cambia la cobertura.

System diagram: Scope Is Applied in Layers

-headless controla Chromium y ejecuta los scripts de la página. En este caso, fue el único modo de Katana probado que recuperó la ruta ensamblada a partir de fragmentos e inyectada en el DOM en tiempo de ejecución. Ese resultado no demuestra qué podría recuperar cualquier parser futuro ni cualquier otro modo de Katana.

Luego está el modelo de alcance, que es la parte que yo interiorizaría antes de escribir nada en producción.

FlagQué controlaValores / valor por defecto
-fs (field scope)qué hosts entran en juegodn, rdn, fqdn o una regex personalizada — por defecto rdn
-cs y -cosregex de URL que filtran dentro de ese alcance
-kfarchivos conocidos: robots.txt y sitemap.xmlel README indica que requiere una profundidad mínima de 3
-dprofundidad3 por defecto
-resumereanuda un rastreo interrumpido

El orden no es decorativo: decide si una regex de host amplía un rastreo o lo deja vacío sin avisar.

Configuración: un binario, un asterisco

Hay tres formas de instalarlo, y solo una necesita toolchain:

Ruta de instalaciónRequisito
Desde código fuente: go install github.com/projectdiscovery/katana/cmd/katana@latestel requisito declarado es Go 1.25 o superior
Binarios precompilados en la página de releasessin toolchain
Imagen Dockersin toolchain

El mío quedó en ~/go/bin/katana y reportó Current version: v1.6.1 en cada ejecución. Hasta aquí, la típica buena historia de Go: un archivo, sin tiempo de ejecución.

El asterisco está en headless, donde el navegador es un requisito aparte del binario:

Dónde se ejecuta -headlessQué necesita
Mi máquinakatana detectó automáticamente un Chromium ya instalado; no registré la build del navegador ni proporcioné una ruta
Un servidor limpio, según las instrucciones Ubuntu del proyectoapt install google-chrome-stable antes de que headless haga algo
La ruta Dockerejecuta headless con -system-chrome

En un servidor limpio, esa comodidad desaparece. Presupuesta un navegador, no solo un binario, en cuanto -headless entre en tu línea de comandos.

Un detalle menor pero útil si lo ejecutas en CI: katana hace una comprobación de versión contra GitHub al arrancar. -duc la desactiva. En un portátil es ruido; en un runner aislado o con límites de tasa, es un viaje de red por ejecución que no pediste. En mis pruebas de tiempo usé -duc para que las cifras midieran rastreo y no llamadas a casa.

Cómo lo probé

Tres clases de endpoint, elegidas precisamente porque separan los modos. Todo vive en un servidor de fixtures local, y la verdad de referencia se escribió antes de ejecutar cualquier rastreo, así que el recall se mide contra un conjunto fijo y no contra lo que katana decidiera imprimir.

  • Clase A — HTML normal. /page/a, /page/b, /page/c, más una cadena de tres saltos /depth/1 → /depth/2 → /depth/3. Cualquier rastreador debería encontrar esto.
  • Clase B — literales en archivos JavaScript. /api/js-endpoint-7 y /api/js-endpoint-8 existen solo como literales de cadena dentro de /static/app.js enlazado. Se pueden leer sin navegador, si alguien se toma la molestia de leer el JS.
  • Clase C — solo DOM en tiempo de ejecución. Una ruta ensamblada en ejecución a partir de fragmentos ('endpoint' + (6 * 7)) e inyectada en el DOM por script. La cadena /runtime-only/endpoint42 nunca aparece de forma contigua en ningún byte que envía el servidor: ni en el HTML ni en el código fuente JS. Solo la ejecución la revela.

Además, un robots.txt, un sitemap.xml con dos endpoints <loc> que no aparecen en ningún otro sitio, una ruta que devuelve 500, un enlace muerto y un enlace fuera de alcance que apunta a un segundo servidor en otro hostname.

El instrumento importa tanto como el fixture: el servidor contabiliza qué se pidió realmente, así que las afirmaciones sobre scope y resume se basan en la verdad de las peticiones y no en el stdout de katana. Los resultados brutos están en el repo del benchmark si quieres revisar mis cálculos.

La división de cobertura que nadie cuantifica

Measured results chart: Endpoint coverage by Katana mode

La matriz, por modo y clase de endpoint, con -d 4:

ModoEnlaces HTML (A)Cadena de profundidad (A)Literales en JS (B)DOM en tiempo de ejecución (C)
standard4/43/30/2no encontrado
standard -jc4/43/32/2no encontrado
-headless4/43/30/2encontrado
-headless -jc4/43/30/2encontrado

Lee las dos últimas columnas como pareja y el problema salta a la vista. La clase B la encontró exactamente una configuración: el modo estándar con -jc. La clase C la encontraron exactamente dos: ambas ejecuciones headless. No hay ninguna fila con aciertos en ambas columnas. La matriz completa está en discovery-summary.json, donde el campo calculado headless_jc_covers_both aparece como false.

La consecuencia práctica es que “usa headless para tener más cobertura” se queda corto para esta prueba. Headless no añadió la clase B encima del resultado estándar; recuperó la clase C mientras seguía sin ver la clase B. Cubrir todas las clases sembradas en este fixture necesitó dos rastreos y una fusión:

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 fila -headless -jc es la que más me gustaría que el upstream explicara. Añadir el parser de JavaScript a la ejecución headless no recuperó nada: siguió en 0/2 para la clase B, en todas las ejecuciones, incluida una reproducción nueva. Informo del comportamiento; no afirmo haber trazado el mecanismo. No instrumenté el interior de katana para averiguar por qué la ruta del navegador deja de aportar literales de archivos JS. Trátalo como una observación reproducible y un buen issue de GitHub, no como un diagnóstico. (Conviene señalar, además, que la combinación -hl -jc terminó correctamente con código de retorno 0 en v1.6.1 sobre macOS ARM, algo que históricamente no siempre había sido así.)

La documentación oficial describe headless como una vía de mayor cobertura, y aquí sí mejoró la clase renderizada en runtime. La guía revisada no explicaba esta división entre literales de fuente y DOM en tiempo de ejecución, así que toma la matriz como una razón para probar ambas rutas contra tus propias clases de endpoint, no como una taxonomía universal.

Qué cuesta headless en tiempo real

Tres ejecuciones secuenciales por modo en una máquina por lo demás inactiva:

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

Eso da una relación de 5.1x, con rangos que ni se acercan a solaparse: mi ejecución estándar más lenta (13.17s) todavía superó a mi ejecución headless más rápida (66.78s) por más de 53 segundos (cost-summary.json). Esto no es ruido de medición.

Un matiz sobre esos 13 segundos: mi fixture incluye deliberadamente una ruta 500 y un enlace muerto, y el modo estándar se queda esperando el tramo de reintento por defecto -timeout 10 en ambos casos. No ajusté el timeout para favorecer al modo rápido, así que una ejecución estándar afinada probablemente ensancharía la brecha en lugar de cerrarla.

La relación es una señal de capacidad local, no una previsión de producción. Los objetivos reales varían en latencia, fallos, trabajo de scripts y planificación, mientras que este fixture incluye un tramo de timeout por defecto. Usa la diferencia medida de 5.1x para decidir si headless merece un presupuesto y un subconjunto de objetivos propios, y luego valida ese plan en hosts representativos y autorizados.

El alcance se mantuvo, pero un flag no hizo nada en silencio

La prueba de scope usó dos servidores: el principal en 127.0.0.1 y un segundo accesible como localhost en otro puerto, que sirve una ruta que existe solo allí. Así que un acierto sobre esa ruta prueba que el host fuera de alcance realmente se pidió, no solo se imprimió.

Configuración¿Se pidió el host fuera de alcance?Hits en el segundo servidor
por defecto (-fs rdn)no0
-fs fqdnno0
-cs localhostno0
`-fs '(127.0.0.1localhost)'`

La disciplina de scope es una buena noticia: por defecto katana se quedó en casa, y solo hizo falta una acción explícita para ampliarlo. Ese es el comportamiento correcto para una herramienta que se apunta a infraestructuras ajenas.

La fila interesante es -cs localhost. No amplió el rastreo al segundo host y, además, emitió cero URLs. Como -cs filtra dentro del field scope, y el field scope seguía siendo el host principal, la regex no coincidió con nada y el rastreo devolvió un conjunto vacío en lugar de un error. Si alguna vez has escrito una regex de alcance nombrando un host que querías incluir y te has quedado mirando un archivo de salida vacío, ese es el mecanismo (scope-summary.json). Para añadir un host, usa -fs. Para estrechar dentro de hosts que ya tienes, usa -cs/-cos.

Resume es más grueso de lo que sugiere el flag

El README describe el flag como -resume string resume scan using resume.cfg, lo que suena a un archivo dejado en el directorio de trabajo. No es así. En mi máquina, el checkpoint se escribió en ~/.config/katana/resume-<xid>.cfg: medido, no sacado de una página de documentación, porque la documentación no indica una ruta.

Lo más importante es lo que había dentro. El archivo contenía un mapa InFlightUrls con exactamente una cosa: la URL semilla. No el conjunto visitado, ni el frente de rastreo. Esto fue lo que pasó cuando interrumpí un rastreo con SIGINT tras tres segundos y luego lo reanudé:

EjecuciónRutas distintas
Rastreo base completo11
Obtenidas antes de la interrupción10
Vuelve a pedir la ejecución reanudadalas 11, incluidas las 10 que ya habían terminado

Resume llegó al mismo conjunto final de endpoints, así que no hay nada roto. Pero la granularidad del checkpoint es por seed de entrada, no por URL: el filtro de deduplicación en memoria nunca se persiste, así que reanudar un rastreo de un solo seed vuelve a rastrearlo desde cero (resume-summary.json). Si le das a katana una lista de 500 hosts, resume debería ahorrarte los hosts que terminaron por completo; ese comportamiento multiseed se deriva de cómo se almacena el estado, pero yo solo medí el caso de un solo seed. Si estás metido a fondo en un sitio enorme, resume te aporta corrección, no tiempo.

Archivos conocidos: solicitados, pero descartados

System diagram: Known files: requested, then dropped

-kf all -d 3 sí solicitó ambos archivos — robots.txt y sitemap.xml aparecieron en el registro de hits del servidor — y luego recuperó 0 de 2 de los endpoints listados en los elementos <loc> de ese sitemap. Recall 0.0.

Antes de llamar a eso una limitación, intenté demostrar que el problema era mío. Todas las variaciones recuperaron lo mismo:

Variación probadaEndpoints <loc> del sitemap recuperados
-kf all0/2, recall 0.0
-kf sitemapxml0/2, recall 0.0
-kf robotstxt0/2, recall 0.0
profundidad 30/2, recall 0.0
profundidad 40/2, recall 0.0
profundidad 50/2, recall 0.0
con -jc añadido0/2, recall 0.0
sembrado directamente en /sitemap.xml0/2, recall 0.0

El requisito documentado — usar -kf y llegar al menos a profundidad tres — se cumplió siempre. No es un caso de flag ausente.

La decisión útil viene antes: en este fixture con IP literal, no asumas que pedir archivos conocidos significa que sus URLs <loc> se incorporaron al rastreo. Verifica el recall o extrae y siembra esas URLs tú mismo.

La ruta de código de v1.6.1 encaja con la observación, pero no la instrumenté durante la ejecución. En sitemapxml.go en v1.6.1, NewNavigationRequestURLFromResponse construye solicitudes de navegación para <loc> desde una respuesta sin un RootHostname poblado. Luego la solicitud pasa a ValidateScope; en scope.go en v1.6.1, la rama para IP literal compara el host de la URL con ese root vacío y puede rechazarla. El comando personalizado -fs '(127.0.0.1|localhost)' tomó otra rama de scope en una prueba distinta, así que es un rescate previsto por el código fuente, no un atajo medido para -kf. Un intento de confirmación quedó bloqueado por problemas intermitentes de conexión en el cliente de known-files en este host; por eso el resultado informado sigue siendo 0/2.

Lo que yo haría en producción, hasta que alguien confirme el flag, es esto: pedir el sitemap yo mismo, extraer las URLs <loc> y pasárselas a katana como lista semilla. Dos líneas de shell, sin validación de scope de por medio.

Hubo algo que funcionó exactamente como decía la documentación y merece una frase: la ruta 500 y el enlace muerto se solicitaron, se registraron y se ignoraron sin romper el rastreo. Todas las ejecuciones sin navegador terminaron con código de retorno 0. Un rastreador que muere al primer mal response no sirve sin supervisión, y katana no hace eso.

Una comprobación de cobertura específica del objetivo antes del despliegue

La matriz del fixture sirve sobre todo como plantilla para probar tus propios objetivos autorizados. Define las clases de endpoint antes de correr Katana: enlaces normales, literales en scripts enlazados, rutas creadas solo tras la ejecución y entradas de archivos conocidos son cuatro cubos razonables para empezar. Conserva una pequeña muestra de verdad de referencia para cada clase. Sin esa lista previa, un stdout más grande puede parecer mejor cobertura incluso cuando una clase ha desaparecido.

Ejecuta primero las rutas sin navegador y headless como mediciones separadas. Guarda los comandos exactos, la versión de Katana, la build del navegador, los códigos de retorno y las salidas. Normaliza y compara los conjuntos de endpoints en lugar de comparar líneas. Si -jc estándar no aporta nada único en tu muestra, quizá baste una política solo headless; si los conjuntos divergen como aquí, mantén los dos pasos separados y fusiona después de recolectar. No asumas que añadir ambas flags a un solo comando equivale a la unión hasta que la diferencia específica del objetivo lo demuestre.

Valida el alcance con evidencia fuera del output de Katana. Coloca una URL canario en un host que deba seguir excluido e inspecciona el log de peticiones de ese servidor. También prueba un segundo host previsto si el rastreo se supone que debe ampliarse. La ejecución -cs localhost aquí produjo salida vacía porque el filtrado de contenido no amplió el field scope; la invocación personalizada -fs '(127.0.0.1|localhost)' sí contactó con el segundo servidor. Registrar la expresión regular exacta importa porque un cambio de un solo carácter puede alterar la regex, no solo su presentación.

Prueba la interrupción y los archivos conocidos por separado del recall de descubrimiento. Para resume, interrumpe un seed representativo tras varias páginas, guarda la ruta del checkpoint generado y cuenta cuántas URLs ya completadas se vuelven a solicitar. Para -kf, confirma tanto que robots/sitemap fueron solicitados como que las URLs <loc> sembradas se programaron realmente. Son afirmaciones distintas. En este fixture los archivos se obtuvieron mientras los dos endpoints del sitemap estaban ausentes, así que tanto los logs de petición como la salida de endpoints fueron necesarios para ver el límite.

Por último, establece una línea base local de coste con ejecuciones secuenciales en una máquina ociosa y luego repite en hosts representativos. Conserva mínimo, máximo y mediana, no solo un multiplicador. La cifra 5.1x aquí incluye el comportamiento de fallo y timeout de este fixture; te dice que headless merece su propio presupuesto, no cuánto tardará un inventario de producción.

Pros y contras

Pros:

  • Recall perfecto sobre HTML normal en todos los modos: 4/4 enlaces y la cadena completa de 3/3 saltos, sin necesidad de configuración.
  • -jc funciona de verdad sin navegador: 2/2 endpoints recuperados desde literales en un archivo JS enlazado, sin coste de navegador.
  • -headless es lo único que encontró un endpoint ensamblado en tiempo de ejecución, una clase que por construcción es invisible al parsing de fuente.
  • Los valores por defecto de alcance son conservadores. El host fuera de alcance nunca se pidió con el valor por defecto, -fs fqdn ni -cs.
  • Un solo binario en Go, licencia MIT, builds precompiladas e imagen Docker, con E/S pensada para pipelines.
  • Robusto ante fallos: los 500 y los enlaces muertos no detienen el rastreo.

Contras:

  • Ninguna invocación cubrió a la vez los endpoints de archivos JS y los de DOM en runtime. La cobertura completa requiere dos ejecuciones y una fusión.
  • -jc no aportó nada bajo -headless: 0/2 en la clase B en todas las ejecuciones headless.
  • Headless cuesta 5.1x más tiempo real (p50 de 66.82s frente a 13.08s, con rangos no solapados).
  • -resume vuelve a rastrear páginas ya completadas dentro de un seed. Recupera el conjunto de endpoints, no el tiempo invertido.
  • Los archivos conocidos pidieron robots.txt y sitemap.xml, pero recuperaron 0/2 endpoints <loc> del sitemap contra un objetivo IP.
  • Headless requiere silenciosamente Chromium en la máquina; la historia del “un solo binario” se termina en el navegador.
  • Solo descubrimiento. Sin extracción estructurada, sin conversión de contenido y sin esquema de campos.

No probados, y por tanto fuera de lo que cubren estas cifras: -jsluice, una prueba específica de corte de profundidad en -d 1/-d 2, resume multiseed, autocompletado de formularios y cualquier sitio real de producción con mucho JavaScript o protegido. Todas las cifras provienen de una sola máquina (macOS arm64) contra un fixture local.

Para quién es y quién debería saltárselo

Si tu trabajo consiste en producir un inventario de endpoints de infraestructuras que estás autorizado a tocar, katana tiene la forma correcta de pipeline: plumbing de STDIN/STDOUT, un binario distribuible y modos con y sin navegador. La fusión en dos pasadas fue necesaria para las clases sembradas en este fixture; si tus objetivos necesitan ambas pasadas es algo que debes establecer a partir de páginas representativas.

Sáltatelo si lo que quieres son datos y no direcciones. Katana nunca te entregará una tabla de productos; te da las URLs donde podrían vivir esos productos, y otra herramienta hace la extracción. Sáltatelo también si necesitas que un solo comando sea completo: la fusión de dos pasadas va bien en un pipeline y resulta incómoda en una terminal. Y si tu enumeración depende de endpoints <loc> de sitemap mientras apuntas a IPs, verifica qué estás recibiendo antes de confiar en la salida, porque en mi fixture esa ruta no devolvió nada.

Alternativas y el límite de la extracción

Katana es gratis, de licencia MIT y autoalojado. Mantiene el descubrimiento, la selección de modo, el despliegue del navegador y la fusión de resultados de tu lado del límite.

Dentro del open source, las comparaciones útiles son por tarea, no por lenguaje. Colly es la otra opción en Go, pero es una librería que compilas con tus propios callbacks y no renderiza JavaScript. Crawl4AI ejecuta un navegador real y produce Markdown para pipelines de LLM, que es otra salida completamente distinta. Si estás valorando varias a la vez, nuestro resumen de scrapers open source coloca las categorías lado a lado.

Divulgación: Thunderbit es el producto del editor y no se probó en este fixture de Katana. Se sitúa aguas abajo en la categoría de extracción gestionada, convirtiendo páginas en texto o registros estructurados en lugar de enumerar la superficie de endpoints de un objetivo autorizado. Un flujo de trabajo puede usar ambas categorías, pero esta revisión aporta pruebas solo del comportamiento de descubrimiento de Katana.

Probar Thunderbit para extracción de datos web

Veredicto

Usa katana cuando el entregable sea una lista de endpoints para objetivos que estás autorizado a rastrear y puedas validar la cobertura por modo contra esos objetivos. En este fixture, -jc estándar recuperó los literales JavaScript sembrados, mientras que headless recuperó el endpoint insertado en el DOM en runtime; los modos sin navegador probados de Katana no recuperaron esa ruta en ejecución. El alcance por defecto también dejó sin pedir el segundo host, y las ejecuciones sin navegador siguieron adelante tras el 500 y el enlace muerto.

Las advertencias son operativas: puede que haga falta una fusión en dos pasadas para clases mixtas de endpoints, headless tardó aproximadamente cinco veces más en tiempo local, resume de un solo seed volvió a pedir rutas ya completadas, y el recall de known-files fue 0/2 contra el objetivo IP. Son resultados de este fixture en v1.6.1, no garantías sobre todos los sitios. Bastan, eso sí, para definir las comprobaciones que una evaluación de producción debería repetir.

Probar Thunderbit para extracción de datos web Get Started Free

Preguntas frecuentes

¿Dónde guarda katana su archivo de resume y reanudar evita las páginas que ya rastreé? El checkpoint quedó en ~/.config/katana/resume-<xid>.cfg, no en un resume.cfg del directorio de trabajo como sugiere la ayuda del flag. Y no, no omite las páginas ya completadas: el archivo solo almacena las URLs semilla en curso, así que al reanudar un rastreo de un solo seed se volvieron a pedir las 11 rutas base, incluidas las 10 que ya estaban terminadas. Se obtiene el mismo conjunto final de endpoints, pero no el tiempo ahorrado.

¿Por qué -kf all pidió mi sitemap.xml pero no rastreó las URLs que contiene? Contra un objetivo IP, el resultado encaja con un límite de validación de scope más que con un error de flag. En el código de v1.6.1, el parser de sitemap de Katana construye cada solicitud <loc> sin arrastrar el hostname raíz, y la comprobación de scope DNS para hosts con IP literal puede rechazar esa URL; no instrumenté la ejecución para confirmar ese mecanismo. Se mantuvo en 0 de recall en todas las combinaciones de flag, profundidad y semilla que probé. Una regex de host personalizada con -fs toma otra rama de validación y es la corrección que predice el código fuente, pero no pude confirmarla con -kf en mi máquina, así que trátalo como no probado. Extraer tú mismo las URLs <loc> y sembrarlas en katana es el enfoque en el que confiaría hoy.

¿Qué debo conservar al informar una prueba de cobertura de Katana? Registra la versión exacta de Katana y el comando, incluida la expresión -fs byte a byte; define las clases de endpoint antes de la ejecución; conserva los logs de hits del servidor además del stdout; y separa el comportamiento medido de las hipótesis basadas en el código fuente. En las ejecuciones headless, registra también la build del navegador; esta prueba no lo hizo, lo que limita la reproducción.

¿Debería usar -jc, -headless o ambos? Elige según las clases de endpoint que necesites. En este fixture, -jc estándar encontró literales guardados en un archivo JavaScript, mientras que headless encontró el endpoint insertado en el DOM en runtime. Ningún modo cubrió ambas clases por sí solo, así que una ejecución en dos pasadas seguida de deduplicación fue la opción defendible para objetivos mixtos.

¿Una URL fallida detendrá el rastreo? No lo hizo en esta ejecución controlada. Katana continuó después de una respuesta 500 y de un enlace muerto, y aun así devolvió las demás rutas alcanzables. Eso no sustituye el control de errores en producción: conserva logs de peticiones fallidas y define una tasa de fallo aceptable para que un rastreo parcialmente exitoso no se confunda con cobertura completa.

Ke
Ke
CTO en Thunderbit | Científico de datos sénior y experto en ML Con casi una década de experiencia en aprendizaje automático y ciencia de datos, Ke Shen es exalumno de la Universidad de Columbia y antiguo científico de datos sénior en Walmart Labs. Con una sólida experiencia, reconocida por sus pares, en Python, R, Java y estadística, comparte conocimientos probados en el campo sobre cómo llevar algoritmos complejos de IA desde la teoría hasta una arquitectura lista para producción.
Topics
Herramientas de web scrapingAI Web Scraper
Tabla de contenidos
Thunderbit · Agente de datos web con IA

Extrae datos de cualquier página en 1 clic

Con la confianza de más de 250.000 usuarios
plan gratuito disponible
De la página web a la hoja de cálculo
Describe lo que necesitas — el agente de IA de Thunderbit lo extrae y lo exporta a Excel, Google Sheets, Airtable o Notion. Empieza gratis.
Chrome Store Rating
PRODUCT HUNT#1 Product of the Week