Análise do Katana: `-jc` e `-headless` Encontram Endpoints Diferentes, e Nenhum Único Comando Encontrou Ambos

Última atualização em August 17, 2026
Análise do Katana: `-jc` e `-headless` Encontram Endpoints Diferentes, e Nenhum Único Comando Encontrou Ambos
Resumo com IA
Katana é o crawler de descoberta de endpoints da ProjectDiscovery — um binário Go, sob licença MIT, que recebe um alvo e devolve URLs e endpoints para a próxima ferramenta de um pipeline. Ele rastreia em modo HTTP sem navegador ou com -headless, que usa o Chromium. A orientação oficial apresenta o modo headless como a opção com maior cobertura; este teste mostra por que o tipo de endpoint importa tanto quanto a quantidade. Montei um pequeno site com três classes de endpoints propositalmente diferentes e medi qual modo encontrou cada uma na v1.6.1 com -d 4.

Katana é o crawler de descoberta de endpoints da ProjectDiscovery — um binário Go, sob licença MIT, que recebe um alvo e devolve URLs e endpoints para a próxima ferramenta de um pipeline. Ele rastreia em modo HTTP sem navegador ou com -headless, que usa o Chromium. A orientação oficial apresenta o modo headless como a opção com maior cobertura; este teste mostra por que o tipo de endpoint importa tanto quanto a quantidade.

Montei um pequeno site com três classes de endpoints propositalmente diferentes e medi qual modo encontrou cada uma na v1.6.1 com -d 4. O HTML comum alcançou 4/4 links e a cadeia completa de três saltos em todas as quatro configurações. A divisão apareceu nos endpoints expostos via código JavaScript versus alterações no DOM em tempo de execução.

Neste teste, o headless encontrou a classe de DOM em tempo de execução que os modos sem navegador avaliados não viram, enquanto o modo padrão com -jc encontrou literais em arquivos JavaScript que ambos os testes headless perderam. Nenhuma linha da matriz com quatro comandos cobriu as duas classes. Escopo, retomada e comportamento de arquivos conhecidos trouxeram os outros limites práticos.

O que o katana realmente é

O crawler katana — projectdiscovery/katana no GitHub — é escrito em Go e licenciado sob MIT. Testei a v1.6.1 em 27 de julho de 2026; a versão importa porque os resultados de cobertura e arquivos conhecidos abaixo são observações específicas dessa build.

O rótulo da categoria é mais importante do que o normal aqui. Um crawler de descoberta de endpoints não é um extrator de campos. Se você quer um web crawler em Go que entregue nomes de produto e preços em JSON estruturado, o katana está na prateleira errada — ele vai dizer com prazer que /products/1138 existe, mas não vai informar nada sobre o conteúdo dessa página. Isso é intencional, e julgá-lo pela extração seria como avaliar um detector de metais pela capacidade de estimar o valor de joias.

Seu território natural é reconhecimento para segurança ofensiva e automação de pipelines: entra via STDIN, sai via URLs, e você o encadeia com a próxima ferramenta. Isso traz à tona o aviso óbvio — todas as medições aqui foram feitas contra um ambiente local em 127.0.0.1 que eu mesmo criei. Use o katana apenas em alvos que você possui ou para os quais tem autorização por escrito, e em mais nada. Nada disso tem a ver com burlar defesas; trata-se de medir quanto da superfície de endpoints de um site um determinado comando realmente enumera.

Os três modos e o que cada um enxerga

O modo padrão é um cliente HTTP em Go. Ele faz a requisição, faz parse do HTML, segue hrefs e nunca inicia um navegador. É rápido, barato e cego para qualquer coisa que só exista depois da execução do JavaScript.

-jc (-js-crawl) adiciona um analisador de JavaScript ao caminho sem navegador. Ele baixa arquivos .js vinculados e extrai literais em forma de URL do código-fonte. Sem execução, só leitura. Existe também o -jsl (jsluice), descrito no README como um parser mais pesado e intensivo em memória — eu não testei, então não posso dizer se ele muda o quadro de cobertura.

System diagram: Scope Is Applied in Layers

-headless controla o Chromium e executa os scripts da página. Neste teste, foi o único modo do Katana que recuperou o caminho montado a partir de fragmentos e inserido no DOM em tempo de execução. Esse resultado não prova o que qualquer parser ou futuro modo do Katana poderia recuperar.

Depois há o modelo de escopo, que é a parte que eu gravaria antes de digitar qualquer coisa em produção.

FlagO que controlaValores / padrão
-fs (field scope)quais hosts entram no jogodn, rdn, fqdn ou uma regex personalizada — o padrão é rdn
-cs e -cosregex de URL que filtram dentro desse escopo de host
-kfarquivos conhecidos: robots.txt e sitemap.xmlo README diz que exige profundidade mínima de 3
-dprofundidadepadrão 3
-resumeretoma um rastreamento interrompido

A ordem não é decorativa: ela decide se uma regex de host amplia o rastreamento ou o esvazia silenciosamente.

Configuração: um binário, um asterisco

Três formas de instalação, e só uma delas precisa de toolchain:

Forma de instalaçãoPré-requisito
A partir do código-fonte: go install github.com/projectdiscovery/katana/cmd/katana@latestGo 1.25 ou mais recente é o requisito informado
Binários pré-compilados na página de releasesem toolchain
Imagem Dockersem toolchain

O meu ficou em ~/go/bin/katana e mostrou Current version: v1.6.1 em toda execução. Até aqui, a clássica e agradável história do Go: um arquivo, nenhum runtime.

O asterisco é o headless, onde o navegador é um pré-requisito separado do binário:

Onde o -headless rodaO que precisa
Na minha máquinao katana detectou automaticamente um Chromium já instalado; não anotei a build do navegador nem informei um caminho explícito
Em um servidor básico, segundo as instruções Ubuntu do projetoapt install google-chrome-stable antes de o headless fazer qualquer coisa
Pela rota Dockerexecuta headless com -system-chrome

Em um servidor básico, essa conveniência desaparece. Reserve orçamento para um navegador, não apenas para um binário, assim que -headless entrar na linha de comando.

Um detalhe menor, mas importante se você usar isso em CI: o katana faz uma chamada de verificação de versão ao GitHub na inicialização. -duc desativa isso. Num notebook, é ruído; em um runner sem internet ou com limite de requisições, é uma ida e volta de rede por execução que você não pediu. Meus testes de tempo usam -duc, para que os números meçam o rastreamento e não a chamada para casa.

Como eu testei

Três classes de endpoint, escolhidas de propósito para separar os modos. Tudo vive em um servidor de fixture local, e a verdade de referência foi anotada antes de qualquer rastreamento rodar, para que o recall fosse medido contra um conjunto fixo — e não contra o que o katana por acaso imprimiu.

  • Classe A — HTML simples. /page/a, /page/b, /page/c, além de uma cadeia de três saltos /depth/1 → /depth/2 → /depth/3. Qualquer crawler deveria capturar isso.
  • Classe B — literais em arquivo JavaScript. /api/js-endpoint-7 e /api/js-endpoint-8 existem apenas como literais de string dentro de um /static/app.js vinculado. Legíveis sem navegador, se alguém se der ao trabalho de ler o JS.
  • Classe C — apenas DOM em tempo de execução. Um caminho montado em tempo de execução a partir de fragmentos ('endpoint' + (6 * 7)) e injetado no DOM por script. A string /runtime-only/endpoint42 nunca aparece de forma contínua em nenhum byte enviado pelo servidor — nem no HTML, nem no código JS. Só a execução revela isso.

Além disso, havia um robots.txt, um sitemap.xml com dois endpoints <loc> que não aparecem em nenhum outro lugar, uma rota que retorna 500, um link quebrado e um link fora de escopo apontando para um segundo servidor em outro hostname.

O instrumento importa tanto quanto o fixture: o servidor conta o que de fato foi buscado, então as afirmações de escopo e retomada se baseiam em hits reais e não na stdout do próprio katana. As execuções brutas estão registradas no repositório do benchmark se você quiser conferir minhas contas.

A divisão de cobertura que ninguém quantifica

Measured results chart: Endpoint coverage by Katana mode

A matriz por modo e por classe de endpoint, em -d 4:

ModoLinks HTML (A)Cadeia de profundidade (A)Literais em JS (B)Runtime-DOM (C)
standard4/43/30/2não encontrado
standard -jc4/43/32/2não encontrado
-headless4/43/30/2encontrado
-headless -jc4/43/30/2encontrado

Leia as duas últimas colunas em conjunto e o problema salta aos olhos. A classe B foi encontrada por exatamente uma configuração: o modo padrão com -jc. A classe C foi encontrada por exatamente duas: ambos os testes headless. Não existe nenhuma linha com acerto nas duas colunas. A matriz completa está em discovery-summary.json, onde o campo calculado headless_jc_covers_both aparece como false.

A consequência prática é que “é só usar headless para ter mais cobertura” ficou incompleto neste teste. O headless não adicionou a classe B ao resultado padrão; ele recuperou a classe C enquanto perdia a classe B. Cobrir todas as classes planejadas neste fixture exigiu dois rastreamentos e um merge:

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

A linha -headless -jc é a que eu mais gostaria de ver respondida pelo upstream. Adicionar o parser de JavaScript à execução headless não recuperou nada — continuou em 0/2 na classe B, em todas as execuções, inclusive numa reprodução nova. Estou relatando o comportamento, não dizendo que rastreei o mecanismo; não instrumentei os internos do katana para descobrir por que o caminho do navegador deixa de contribuir com literais de arquivos JS. Trate isso como uma observação reproduzível e um bom issue no GitHub, não como um diagnóstico. (Vale notar em paralelo: a combinação -hl -jc foi concluída normalmente com código de retorno 0 na v1.6.1 em macOS ARM, o que historicamente nem sempre aconteceu.)

A documentação oficial descreve o headless como oferecendo melhor cobertura, e isso aconteceu aqui para a classe renderizada em tempo de execução. A orientação revisada não detalhou essa divisão entre literal de origem e DOM em tempo de execução, então use a matriz como motivo para testar os dois caminhos contra suas próprias classes de endpoint — não como uma taxonomia universal.

Quanto o headless custa em tempo total

Três execuções sequenciais por modo, em uma máquina ociosa:

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

Isso dá uma proporção de 5,1x, com faixas que nem chegam perto de se sobrepor — minha execução standard mais lenta (13.17s) ainda foi mais de 53 segundos mais rápida que a execução headless mais veloz (66.78s) (cost-summary.json). Isso não é ruído de medição.

Um ponto de atenção nesses 13 segundos: minha fixture inclui deliberadamente uma rota 500 e um link quebrado, e o modo standard aguenta o atraso padrão de retry do -timeout 10 nos dois casos. Eu não ajustei o timeout para favorecer o modo rápido, o que significa que uma execução standard afinada provavelmente aumentaria a diferença em vez de reduzi-la.

A proporção é um sinal local de capacidade, não uma previsão de produção. Alvos reais variam em latência, falhas, trabalho de script e agendamento, enquanto esta fixture inclui a cauda do timeout padrão. Use a diferença medida de 5,1x para decidir se o headless merece orçamento e subconjunto de alvos próprios, e então valide esse plano em hosts autorizados e representativos.

O escopo se manteve, mas uma flag não fez nada de forma silenciosa

O teste de escopo usou dois servidores: o principal em 127.0.0.1 e um segundo acessível como localhost em outra porta, servindo um caminho que existe apenas ali. Portanto, um hit nesse caminho prova que o host fora de escopo realmente foi buscado, e não apenas impresso.

ConfiguraçãoHost fora de escopo foi buscado?Hits no segundo servidor
padrão (-fs rdn)não0
-fs fqdnnão0
-cs localhostnão0
`-fs '(127.0.0.1localhost)'`sim

A disciplina de escopo é uma boa notícia: por padrão o katana ficou em casa, e foi preciso uma ação explícita para ampliar. Esse é o comportamento correto para uma ferramenta apontada para infraestrutura de terceiros.

A linha interessante é -cs localhost. Ela não ampliou o rastreamento para o segundo host — e também produziu zero URLs. Como -cs filtra dentro do escopo de campo, e o escopo de campo ainda era o host principal, a regex não correspondeu a nada e o rastreamento devolveu um conjunto vazio em vez de um erro. Se você já escreveu uma regex de escopo para incluir um host e encarou um arquivo de saída vazio, esse é o mecanismo (scope-summary.json). Para adicionar um host, use -fs. Para restringir dentro dos hosts que você já tem, use -cs/-cos.

A retomada é mais grossa do que a flag sugere

O README descreve a flag como -resume string resume scan using resume.cfg, o que soa como um arquivo deixado no diretório atual. Não é. Na minha máquina, o checkpoint foi gravado em ~/.config/katana/resume-<xid>.cfg — medido, não lido de uma página de docs, porque a documentação não informa o caminho.

O conteúdo é a surpresa mais importante. O arquivo continha um mapa InFlightUrls com exatamente uma coisa: a URL semente. Não o conjunto visitado, nem a fronteira. Então foi isso que aconteceu quando interrompi um rastreamento com SIGINT após três segundos e depois o retomei:

ExecuçãoCaminhos distintos
Rastreamento completo de referência11
Buscados antes da interrupção10
Buscados novamente pela retomadatodos os 11, incluindo os 10 que já tinham sido concluídos

A retomada chegou ao mesmo conjunto final de endpoints, então nada está quebrado. Mas a granularidade do checkpoint é por semente de entrada, não por URL — o filtro de deduplicação em memória nunca é persistido, então retomar um rastreamento de uma única semente faz com que ela seja rastreada de novo do zero (resume-summary.json). Se você alimentar o katana com uma lista de 500 hosts, a retomada deve poupar os hosts que já terminaram por completo; esse comportamento com múltiplas sementes decorre de como o estado é armazenado, mas eu só medi o caso de uma única semente. Se você estiver preso em um site enorme, a retomada compra correção, não tempo.

Arquivos conhecidos: solicitados, depois descartados

System diagram: Known files: requested, then dropped

-kf all -d 3 realmente solicitou ambos os arquivos — robots.txt e sitemap.xml apareceram no log de hits do servidor — e depois recuperou 0 de 2 dos endpoints listados nos elementos <loc> desse sitemap. Recall 0,0.

Antes de chamar isso de limitação, tentei fazer parecer que era culpa minha. Todas as variações recuperaram o mesmo resultado:

Variação testadaEndpoints <loc> do sitemap recuperados
-kf all0/2, recall 0,0
-kf sitemapxml0/2, recall 0,0
-kf robotstxt0/2, recall 0,0
profundidade 30/2, recall 0,0
profundidade 40/2, recall 0,0
profundidade 50/2, recall 0,0
com -jc adicionado0/2, recall 0,0
com semente direta em /sitemap.xml0/2, recall 0,0

O requisito documentado — usar -kf, ir pelo menos três níveis fundo — foi atendido em todas as tentativas. Isso não é uma história de flag ausente.

A decisão útil vem primeiro: neste fixture com IP literal, não assuma que solicitar arquivos conhecidos significa que os URLs <loc> deles entraram no rastreamento. Verifique o recall ou extraia e forneça esses URLs manualmente.

O caminho de código da v1.6.1 é coerente com a observação, mas eu não o instrumentei durante a execução. Em sitemapxml.go na v1.6.1, NewNavigationRequestURLFromResponse monta pedidos de navegação <loc> a partir de uma resposta sem um RootHostname preenchido. Em seguida, a requisição chega a ValidateScope; em scope.go na v1.6.1, o ramo de IP literal compara o host da URL com esse root vazio e pode rejeitá-lo. O comando personalizado -fs '(127.0.0.1|localhost)' seguiu outro ramo de escopo em um teste separado, então é um resgate previsto pelo código-fonte, e não uma solução de contorno medida do -kf. Uma tentativa de confirmação foi bloqueada por falhas intermitentes de conexão no cliente de arquivos conhecidos neste host; por isso, o resultado reportado continua sendo 0/2.

O que eu realmente faria em produção, até alguém confirmar a flag: buscar o sitemap manualmente, extrair os URLs <loc> e fornecê-los ao katana como uma lista de sementes. Duas linhas de shell, sem envolvimento de validação de escopo.

Uma coisa se comportou exatamente como anunciado e merece uma frase: a rota 500 e o link quebrado foram buscados, registrados e ignorados. Toda execução sem navegador terminou com código de retorno 0. Um crawler que morre no primeiro erro é inútil sem supervisão, e o katana não faz isso.

Uma checagem de cobertura específica do alvo antes do deploy

A matriz da fixture é mais útil como modelo para testar seus próprios alvos autorizados. Defina as classes de endpoint antes de rodar o Katana: links simples, literais em scripts vinculados, rotas criadas apenas após execução e entradas de arquivos conhecidos são quatro categorias razoáveis para começar. Mantenha uma pequena amostra de verdade de referência para cada classe. Sem essa lista anterior, uma saída maior na stdout pode parecer cobertura melhor mesmo quando uma classe desapareceu.

Execute os caminhos sem navegador e headless como medições separadas primeiro. Salve os comandos exatos, a versão do Katana, a build do navegador, os códigos de retorno e as saídas. Normalize e compare os conjuntos de endpoints em vez de comparar contagens de linhas. Se o -jc padrão não acrescentar nada de único na sua amostra, uma política só com headless pode bastar; se os conjuntos divergirem como aconteceu aqui, mantenha as duas passagens separadas e faça o merge depois da coleta. Não assuma que colocar as duas flags em um único comando equivale à união dos resultados até que o diff específico do alvo prove isso.

Valide o escopo com evidências fora da saída do Katana. Coloque uma URL-canário em um host que deve permanecer excluído e inspecione o log de requisições desse servidor. Teste também um segundo host pretendido, se o rastreamento for para se ampliar. A execução -cs localhost aqui gerou saída vazia porque o filtro de escopo de conteúdo não expandiu o escopo de campo; a invocação personalizada -fs '(127.0.0.1|localhost)' de fato contatou o segundo servidor. Registrar a regex exata importa porque uma mudança de um caractere pode alterar a própria expressão regular, e não apenas sua apresentação.

Teste interrupção e arquivos conhecidos separadamente do recall de descoberta. Para o resume, interrompa uma semente representativa após algumas páginas, salve o caminho do checkpoint gerado e conte quantas URLs já concluídas são buscadas novamente. Para -kf, confirme tanto que robots/sitemap foram solicitados quanto que os URLs <loc> plantados realmente foram agendados. São afirmações diferentes. Neste fixture, os arquivos foram buscados enquanto os dois endpoints do sitemap estavam ausentes, então tanto os logs de requisição quanto a saída de endpoints foram necessários para enxergar o limite.

Por fim, estabeleça uma linha de base de custo local usando execuções sequenciais em uma máquina ociosa e repita isso em hosts representativos. Preserve mínimo, máximo e mediana, e não apenas um multiplicador. A cifra de 5,1x aqui inclui o comportamento de falha e timeout desta fixture; ela diz que o headless merece orçamento próprio, não quanto tempo um inventário de produção vai levar.

Prós e contras

Prós:

  • Recall perfeito em HTML comum em todos os modos — 4/4 links e a cadeia completa de profundidade 3/3, sem necessidade de configuração.
  • -jc funciona de verdade sem navegador: 2/2 endpoints recuperados a partir de literais de string em um arquivo JS vinculado, sem custo de browser.
  • -headless foi o único recurso que encontrou um endpoint montado em tempo de execução — uma classe que é invisível para a análise de origem por definição.
  • Os padrões de escopo são conservadores. O host fora de escopo nunca foi buscado no padrão, em -fs fqdn ou em -cs.
  • Binário Go único, licença MIT, builds pré-compiladas e imagem Docker, I/O no formato de pipeline.
  • Robusto diante de falhas: respostas 500 e links mortos não interrompem o rastreamento.

Contras:

  • Nenhuma invocação única cobriu endpoints em arquivo JS e em DOM em tempo de execução. Cobertura completa exige duas execuções e um merge.
  • -jc não acrescentou nada sob -headless — 0/2 na classe B em todas as execuções headless.
  • O headless custa 5,1x o tempo total de execução (p50 de 66.82s contra 13.08s, com faixas sem sobreposição).
  • -resume rastreia novamente páginas já concluídas dentro de uma mesma semente. Ele restaura o conjunto de endpoints, não o tempo gasto.
  • Arquivos conhecidos solicitaram robots.txt e sitemap.xml, mas recuperaram 0/2 endpoints <loc> do sitemap contra um alvo por IP.
  • O headless exige silenciosamente um Chromium instalado; a história de “um binário só” termina no navegador.
  • Só descoberta. Nenhuma extração estruturada, nenhuma conversão de conteúdo, nenhum esquema de campos.

Não testado, e portanto fora do que qualquer um desses números cobre: -jsluice, um teste dedicado de corte de profundidade em -d 1/-d 2, resume com múltiplas sementes, preenchimento automático de formulários e qualquer site de produção real, pesado em JavaScript ou protegido. Todos os números vêm de uma única máquina (macOS arm64) contra um fixture local.

Para quem ele serve, e quem deveria passar longe

Se o seu trabalho é produzir um inventário de endpoints de uma infraestrutura que você tem autorização para tocar, o katana tem o formato certo de pipeline: plumbing de STDIN/STDOUT, binário distribuível, e modos com e sem navegador. O merge em duas passagens foi necessário para as classes plantadas neste fixture; se os seus alvos exigem ambas as passagens é algo que você deve descobrir a partir de páginas representativas.

Passe longe se você quer dados, não endereços. O Katana nunca vai te entregar uma tabela de produtos; ele entrega as URLs onde os produtos podem viver, e outra ferramenta faz a extração. Passe longe também se você precisa que um único comando seja completo — o merge de duas passagens funciona bem em pipeline e é incômodo no prompt. E, se sua enumeração depende de endpoints <loc> de sitemap enquanto mira IPs, verifique o que realmente está recebendo antes de confiar na saída, porque neste fixture o caminho não devolveu nada.

Alternativas e a fronteira da extração

O Katana é gratuito, sob licença MIT, e auto-hospedado. Ele mantém descoberta, seleção de modo, implantação do navegador e merge dos resultados do seu lado da fronteira.

Dentro do open source, as comparações úteis são por tarefa, não por linguagem. Colly é a outra opção em Go, mas é uma biblioteca que você compila com seus próprios callbacks e não renderiza JavaScript. Crawl4AI roda um navegador real e produz Markdown para pipelines de LLM, o que é um resultado completamente diferente. Se você estiver avaliando vários ao mesmo tempo, nosso resumo de scrapers open source organiza as categorias lado a lado.

Divulgação: Thunderbit é o produto do publisher e não foi testado neste fixture do Katana. Ele fica a jusante na categoria de extração gerenciada, transformando páginas em texto ou registros estruturados em vez de enumerar a superfície de endpoints de um alvo autorizado. Um fluxo pode usar ambas as categorias, mas esta análise fornece evidências apenas do comportamento de descoberta do Katana.

Experimente o Thunderbit para Extração de Dados da Web

Veredito

Use o katana quando o entregável for uma lista de endpoints para alvos que você está autorizado a rastrear e quando puder validar a cobertura por modo nesses alvos. Neste fixture, o -jc padrão recuperou os literais de JavaScript plantados, enquanto o headless recuperou o endpoint inserido no DOM em tempo de execução; os modos sem navegador testados não recuperaram esse caminho dinâmico. O escopo padrão também manteve o segundo host sem busca, e as execuções sem navegador continuaram passando pela resposta 500 e pelo link quebrado.

As ressalvas são operacionais: um merge em duas passagens pode ser necessário para classes de endpoint misturadas, o headless levou cerca de cinco vezes o tempo local total, a retomada de uma única semente buscou novamente os caminhos já concluídos, e o recall dos arquivos conhecidos foi 0/2 contra o alvo por IP. Esses são resultados da v1.6.1 no fixture, não garantias sobre qualquer site. Eles bastam para definir as verificações que uma avaliação em produção deve repetir.

Experimente o Thunderbit para Extração de Dados da Web Get Started Free

FAQs

Onde o katana salva o arquivo de resume, e retomar ignora páginas que eu já rastreei? O checkpoint foi salvo em ~/.config/katana/resume-<xid>.cfg, e não em um resume.cfg no diretório de trabalho, como o help da flag sugere. E não, ele não pula páginas concluídas: o arquivo armazena apenas URLs semente em andamento, então uma retomada de uma única semente buscou novamente todos os 11 caminhos de referência, incluindo os 10 que já estavam prontos. Você obtém o mesmo conjunto final de endpoints, só não economiza o tempo gasto.

Por que o -kf all pediu meu sitemap.xml mas não rastreou os URLs dentro dele? Contra um alvo por IP, isso é um limite de validação de escopo, não um erro de flag. O parser de sitemap do Katana monta cada requisição <loc> sem repassar o hostname raiz, e a checagem de escopo DNS para hosts literais por IP compara o host da URL com esse root vazio, falha na comparação e descarta a URL. Isso se manteve em 0 de recall em todas as variações de flag, profundidade e seed que testei. Uma regex de host personalizada em -fs segue um ramo diferente de validação e é a correção que o código sugere — mas eu não consegui confirmá-la com -kf na minha máquina, então trate isso como não testado. Extrair os URLs <loc> você mesmo e fornecê-los ao katana como sementes é a abordagem em que eu confiaria hoje.

O que devo preservar ao relatar um teste de cobertura do Katana? Registre a versão exata do Katana e o comando, incluindo a expressão -fs byte a byte; defina as classes de endpoint antes da execução; mantenha logs de hits no servidor junto com a stdout; e separe comportamento medido de hipóteses baseadas em código-fonte. Para execuções headless, registre também a build do navegador — este teste não o fez, o que limita a reprodução.

Devo usar -jc, -headless ou ambos? Escolha de acordo com as classes de endpoint de que você precisa. Neste fixture, o -jc padrão encontrou literais armazenados em um arquivo JavaScript, enquanto o headless encontrou o endpoint inserido no DOM em tempo de execução. Nenhum dos modos cobriu as duas classes sozinho, então uma execução em duas passagens seguida de deduplicação foi a escolha defensável para alvos mistos.

Um URL com erro vai interromper o rastreamento? Não interrompeu nesta execução controlada. O Katana continuou depois de uma resposta 500 e de um link quebrado e ainda retornou os outros caminhos alcançáveis. Isso não substitui o controle de erros em produção: mantenha logs de requisições falhas e defina uma taxa de falha aceitável para que um rastreamento parcialmente bem-sucedido não seja confundido com cobertura completa.

Ke
Ke
CTO na Thunderbit | Cientista de Dados Sênior e Especialista em ML Com quase uma década de experiência em machine learning e data science, Ke Shen é ex-aluno da Columbia University e foi Cientista de Dados Sênior na Walmart Labs. Com profunda experiência, reconhecida pelos pares, em Python, R, Java e Estatística, ele compartilha insights testados em batalha sobre como levar algoritmos complexos de IA da teoria à arquitetura pronta para produção.
Sumário
Thunderbit · Agente de dados web com IA

Extraia dados de qualquer página em 1 clique

Aprovado por mais de 250.000 usuários
plano gratuito disponível
Da página web para a planilha
Descreva o que você precisa — o Agente de IA da Thunderbit extrai e exporta para Excel, Google Sheets, Airtable ou Notion. Comece grátis.
Chrome Store Rating
PRODUCT HUNT#1 Product of the Week