CAPSOLVER
Blog
Como resolver AWS Captcha com NodeJS

Como resolver o AWS Captcha com NodeJS

Logo of CapSolver

Adélia Cruz

Neural Network Developer

03-Nov-2025

Na paisagem web moderna, proteger recursos online contra ameaças automatizadas é fundamental. O AWS Web Application Firewall (WAF) é uma camada de segurança robusta que frequentemente implementa desafios ou captchas gerenciados para filtrar bots maliciosos. Embora eficaz para segurança, esses mecanismos representam um obstáculo significativo para tarefas de automação legítimas, como raspagem de web, monitoramento ou testes.

Este guia completo fornece uma solução poderosa e automatizada usando Node.js e o serviço CapSolver. Vamos mostrar como configurar o ambiente, implementar um script Node.js modular e utilizar a tarefa especializada AntiAwsWafTask do CapSolver para contornar os cenários de Desafio WAF (HTTP 202) e de CAPTCHA WAF (HTTP 405). Ao final deste tutorial, você terá um script pronto para produção capaz de obter o cookie aws-waf-token necessário para acessar conteúdo protegido.

⚙️ Pré-requisitos

Antes de começar, certifique-se de ter o seguinte ambiente e informações prontas:

  1. Ambiente Node.js: O Node.js está instalado no seu sistema (versão LTS recomendada).
  2. Chave de API do CapSolver: Você precisa de uma conta no CapSolver e sua chave de API.
  3. Proxy (Opcional): Se o site-alvo tiver restrições geográficas ou você precisar ocultar seu IP real, prepare um proxy HTTP/HTTPS.

🛠️ Etapa Um: Instalar Dependências Necessárias

No seu diretório de projeto, execute o seguinte comando para instalar os módulos Node.js necessários:

bash Copy
npm install axios cheerio
  • axios: Usado para enviar solicitações HTTP.
  • cheerio: Usado para analisar o conteúdo HTML e extrair parâmetros necessários para o desafio AWS WAF.

💻 Etapa Dois: Implementação do Código Principal em Node.js

Abaixo está o script Node.js para resolver Desafios e CAPTCHAS da AWS WAF. Ele detecta automaticamente o código de status retornado pelo site e executa a tarefa do CapSolver correspondente, se necessário.

Por favor, salve o seguinte código como aws_waf_solver.js.

javascript Copy
const axios = require('axios');
const cheerio = require('cheerio');
const { URL } = require('url');

// ⚠️ Configuração: Por favor, substitua pelos seus valores reais
const CLIENT_KEY = "SUA_CHAVE_DE_API_DO_CAPSOLVER"; // Substitua pela sua chave de API do CapSolver
const PAGE_URL = "https://norway-meetup.aws.wslab.no/"; // Substitua pela URL do site-alvo
const PROXY = "SUA_ENDERECO_DE_PROXY"; // Substitua pelo seu endereço de proxy (Formato: user:pass@ip:port ou ip:port)

// --- Funções Auxiliares ---

/**
 * Pausa a execução por um número especificado de milissegundos
 * @param {number} ms Milissegundos
 */
function sleep(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
}

/**
 * Cria uma tarefa com o CapSolver
 * @param {object} payload Payload da tarefa
 * @returns {Promise<object>} Resultado da criação da tarefa
 */
async function createTask(payload) {
    try {
        const res = await axios.post('https://api.capsolver.com/createTask', {
            clientKey: CLIENT_KEY,
            task: payload
        });
        if (res.data.errorId !== 0) {
            throw new Error(`Erro da API do CapSolver: ${res.data.errorDescription}`);
        }
        return res.data;
    } catch (error) {
        console.error("Falha ao criar a tarefa do CapSolver:", error.message);
        return null;
    }
}

/**
 * Obtém o resultado da tarefa do CapSolver até que a tarefa seja concluída
 * @param {string} taskId ID da tarefa
 * @returns {Promise<object>} Resultado da tarefa
 */
async function getTaskResult(taskId) {
    if (!taskId) return null;
    console.log(`Aguardando resultado da tarefa (ID: ${taskId})...`);
    try {
        let success = false;
        let result = null;
        while (!success) {
            await sleep(3000); // Consulta a cada 3 segundos
            const res = await axios.post('https://api.capsolver.com/getTaskResult', {
                clientKey: CLIENT_KEY,
                taskId: taskId
            });

            if (res.data.errorId !== 0) {
                throw new Error(`Erro da API do CapSolver: ${res.data.errorDescription}`);
            }

            if (res.data.status === "ready") {
                success = true;
                result = res.data;
                console.log("Tarefa concluída, solução obtida.");
            } else if (res.data.status === "processing") {
                console.log("A tarefa ainda está em processamento...");
            }
        }
        return result;
    } catch (error) {
        console.error("Falha ao obter o resultado da tarefa do CapSolver:", error.message);
        return null;
    }
}

// --- Funções Principais de Resolução ---

/**
 * Resolve o Desafio AWS WAF (Código de Status 202)
 * @param {string} awsChallengeJS URL do JavaScript do Desafio AWS WAF
 * @returns {Promise<string|null>} Valor do cookie AWS WAF resolvido
 */
async function solveAwsChallenge(awsChallengeJS) {
    console.log("Desafio AWS WAF detectado (Código de Status 202), iniciando a resolução...");
    const taskPayload = {
        type: "AntiAwsWafTask",
        websiteURL: PAGE_URL,
        awsChallengeJS,
        proxy: PROXY
    };
    const taskData = await createTask(taskPayload);
    if (!taskData) return null;

    const result = await getTaskResult(taskData.taskId);
    if (result && result.solution && result.solution.cookie) {
        return result.solution.cookie;
    }
    return null;
}

/**
 * Resolve o CAPTCHA + Desafio AWS WAF (Código de Status 405)
 * @param {string} htmlContent Conteúdo HTML contendo parâmetros de CAPTCHA
 * @param {string} awsChallengeJS URL do JavaScript do Desafio AWS WAF
 * @returns {Promise<string|null>} Valor do cookie AWS WAF resolvido
 */
async function solveAwsCaptchaChallenge(htmlContent, awsChallengeJS) {
    console.log("CAPTCHA AWS WAF detectado (Código de Status 405), iniciando a resolução...");
    const $ = cheerio.load(htmlContent);
    const scriptContent = $("script[type='text/javascript']").last().html();

    if (!scriptContent) {
        console.error("Não foi possível encontrar o conteúdo do script contendo os parâmetros do CAPTCHA.");
        return null;
    }

    // Use expressões regulares para extrair os parâmetros principais
    const keyMatch = /"key":"(.*?)"/.exec(scriptContent);
    const ivMatch = /"iv":"(.*?)"/.exec(scriptContent);
    const contextMatch = /"context":"(.*?)"/.exec(scriptContent);

    const key = keyMatch ? keyMatch[1] : null;
    const iv = ivMatch ? ivMatch[1] : null;
    const context = contextMatch ? contextMatch[1] : null;

    if (!key || !iv || !context) {
        console.error("Falha ao extrair todos os parâmetros necessários do CAPTCHA (key, iv, context) do script.");
        return null;
    }

    console.log(`Parâmetros Extraídos: Key=${key}, IV=${iv}, Context=${context}`);

    const taskPayload = {
        type: "AntiAwsWafTask", // O CapSolver usa este tipo de tarefa uniformemente
        websiteURL: PAGE_URL,
        awsKey: key,
        awsIv: iv,
        awsContext: context,
        awsChallengeJS,
        proxy: PROXY
    };

    const taskData = await createTask(taskPayload);
    if (!taskData) return null;

    const result = await getTaskResult(taskData.taskId);
    if (result && result.solution && result.solution.cookie) {
        return result.solution.cookie;
    }
    return null;
}

/**
 * Função principal de execução
 */
async function main() {
    let awsWafCookie = null;
    let initialResponse = null;

    // 1. Solicitação inicial à página alvo
    try {
        console.log(`Solicitando página alvo: ${PAGE_URL}`);
        initialResponse = await axios.get(PAGE_URL, {
            headers: {
                // Simular cabeçalhos de solicitação de navegador
                "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36",
                "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
                "Accept-Encoding": "gzip, deflate, br",
                "Accept-Language": "en-US,en;q=0.9",
                "Cache-Control": "max-age=0",
                "Upgrade-Insecure-Requests": "1"
            },
            // Permitir processamento de códigos de status 2xx, 3xx, 4xx
            validateStatus: (status) => status >= 200 && status < 500
        });
        console.log(`Código de status da resposta inicial: ${initialResponse.status}`);
    } catch (error) {
        console.error(`Falha na solicitação inicial: ${error.message}`);
        return;
    }

    const $ = cheerio.load(initialResponse.data);
    const scriptTags = $('script[src*="token.awswaf.com"]');
    const awsChallengeJS = scriptTags.attr('src');

    if (!awsChallengeJS) {
        console.log("Script de desafio AWS WAF não detectado. O site pode não estar protegido ou já ter passado.");
        // Se nenhum script de desafio, use a resposta inicial diretamente
        if (initialResponse.status === 200) {
            console.log("Site carregado com sucesso.");
            // console.log(initialResponse.data); // Imprimir conteúdo final
            return;
        }
    } else {
        console.log(`URL do script de desafio AWS WAF detectada: ${awsChallengeJS}`);
    }


    // 2. Determinar e resolver o desafio/captcha com base no código de status
    if (initialResponse.status === 202) {
        // Apenas Desafio AWS WAF
        awsWafCookie = await solveAwsChallenge(awsChallengeJS);
    } else if (initialResponse.status === 405) {
        // CAPTCHA AWS WAF + Desafio
        awsWafCookie = await solveAwsCaptchaChallenge(initialResponse.data, awsChallengeJS);
    } else if (initialResponse.status === 200) {
        console.log("Site carregado com sucesso, nenhuma resolução de CAPTCHA necessária.");
        // console.log(initialResponse.data); // Imprimir conteúdo final
        return;
    } else {
        console.log(`Código de status não tratado encontrado: ${initialResponse.status}.`);
        return;
    }

    // 3. Solicitar novamente a página alvo usando o cookie obtido
    if (awsWafCookie) {
        try {
            console.log("\n--- Segunda Solicitação: Usando Cookie AWS WAF ---");
            console.log(`Cookie usado: ${awsWafCookie}`);

            const finalResponse = await axios.get(PAGE_URL, {
                headers: {
                    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36",
                    "Cookie": `aws-waf-token=${awsWafCookie}`
                },
                validateStatus: (status) => status === 200 // Esperar sucesso final
            });

            console.log(`Código de status da resposta final: ${finalResponse.status}`);
            console.log("Conteúdo do site recuperado com sucesso!");
            // console.log(finalResponse.data); // Imprimir conteúdo final
        } catch (error) {
            console.error(`Falha na solicitação final: ${error.message}`);
        }
    } else {
        console.log("Falha ao obter o Cookie AWS WAF, impossível realizar a segunda solicitação.");
    }
}

main();

💡 Resumo dos Pontos Importantes

Ponto Chave Problema no Código Original Melhoria Otimizada
Instalação de Dependências Faltava cheerio, usava destaque de sintaxe Python incorreto. Destaque de sintaxe bash correto e clara necessidade de instalar axios e cheerio.
Tipo de Tarefa Uso misturado de FunCaptchaTaskProxyless e AntiAwsWafTask. Uso unificado do AntiAwsWafTask recomendado oficialmente pelo CapSolver para todos os cenários de AWS WAF.
Extração de Parâmetros Lógica incompleta para extrair awsChallengeJS na lógica 405, e não extraída na lógica 202. Extração unificada de awsChallengeJS após a solicitação inicial na função main, e chamada de funções de solucionador diferentes com base no código de status (202 ou 405).
Tratamento de Erros Tratamento simples de erros, sem verificação de erros da API e sem mensagens de aguardo da tarefa. Adicionado verificação de erros da API (errorId !== 0) nas funções createTask e getTaskResult, e fornecimento de mensagens de status durante o processamento da tarefa.
Estrutura do Código Toda a lógica estava agrupada na função main, resultando em baixa legibilidade. Dividido em funções auxiliares claras (sleep, createTask, getTaskResult) e funções principais de solucionador (solveAwsChallenge, solveAwsCaptchaChallenge), tornando a lógica mais clara.
Cabeçalhos de Solicitação Cabeçalhos originais eram redundantes e incompletos. Simplificados e usados cabeçalhos de solicitação mais padrão, simulando um navegador.

❓ Perguntas Frequentes (FAQ)

Q: Por que preciso lidar com os códigos de status HTTP 202 e HTTP 405?

A: O AWS WAF usa medidas de segurança diferentes que resultam em códigos de status HTTP diferentes:

  • HTTP 202 (Aceito): Geralmente indica que um Desafio AWS WAF é necessário. É uma verificação de segurança mais leve que envolve a execução de um trecho de JavaScript.
  • HTTP 405 (Método Não Permitido): Indica frequentemente que um CAPTCHA AWS WAF é necessário, que é uma verificação mais complexa que envolve resolver um quebra-cabeça visual ou interativo, junto com os parâmetros do desafio. Nosso script foi projetado para detectar automaticamente e lidar com ambos os cenários.

Q: Posso usar este script sem um proxy?

A: Sim, você pode. A variável PROXY é opcional. Se você não precisar de um proxy, pode definir const PROXY = ""; na configuração. No entanto, é altamente recomendado usar um proxy de alta qualidade para tarefas de raspagem de web e automação para evitar banimentos de IP e garantir acesso consistente.

Q: O que é a AntiAwsWafTask?

A: A AntiAwsWafTask é um tipo de tarefa especializado fornecido pelo CapSolver, projetado especificamente para lidar com o mecanismo de segurança AWS WAF. Ela processa inteligentemente os parâmetros do desafio (incluindo awsKey, awsIv, awsContext e awsChallengeJS) extraídos da página protegida e retorna o cookie aws-waf-token válido necessário para contornar a proteção.

📚 Mais Informações

✅ Conclusão

Este guia demonstrou um método robusto e eficiente para resolver programaticamente desafios e captchas do AWS WAF usando Node.js e CapSolver. Ao implementar o script modular e aproveitar o tipo de tarefa especializada do CapSolver, você pode integrar esta solução de forma transparente em seus fluxos de trabalho de automação. A chave para o sucesso está em identificar corretamente o código de status do WAF (202 ou 405), extrair os parâmetros necessários e usar o cookie aws-waf-token resultante para solicitações subsequentes. Este abordagem garante que suas tarefas de automação possam acessar conteúdo protegido pelo AWS WAF de forma confiável.

Declaração de Conformidade: As informações fornecidas neste blog são apenas para fins informativos. A CapSolver está comprometida em cumprir todas as leis e regulamentos aplicáveis. O uso da rede CapSolver para atividades ilegais, fraudulentas ou abusivas é estritamente proibido e será investigado. Nossas soluções de resolução de captcha melhoram a experiência do usuário enquanto garantem 100% de conformidade ao ajudar a resolver dificuldades de captcha durante a coleta de dados públicos. Incentivamos o uso responsável de nossos serviços. Para mais informações, visite nossos Termos de Serviço e Política de Privacidade.

Mais