
Lucas Mitchell
Automation Engineer

O AWS WAF (Web Application Firewall) é o sistema de proteção de bots de nível empresarial da Amazon usado por alguns dos maiores sites da internet. Ao contrário dos CAPTCHAs tradicionais que exibem quebra-cabeças de imagens ou caixas de seleção, o AWS WAF usa desafios invisíveis e verificação baseada em token, tornando-o particularmente difícil de lidar com ferramentas automatizadas.
E se você pudesse resolver automaticamente os desafios do AWS WAF em seus fluxos de trabalho n8n? Seja você construindo uma API de solução reutilizável, raspando um site protegido por CAPTCHA ou automatizando um formulário de login, você pode fazer tudo isso sem escrever uma única linha de código tradicional.
Neste guia, você aprenderá como combinar n8n (uma ferramenta de automação de fluxo de trabalho visual) com CapSolver (um serviço de solução de CAPTCHA alimentado por IA) para resolver desafios do AWS WAF sob demanda. Isso pode funcionar como um endpoint de API autônomo ou como uma etapa em um fluxo de trabalho de automação maior.
O que vamos construir:
API de Solução — um endpoint reutilizável que outras ferramentas podem chamar:
Fluxos de Trabalho de Uso Direto — incorporando o CapSolver como uma etapa em uma automação maior:
O AWS WAF (Web Application Firewall) é um serviço de mitigação de bots e segurança da web da Amazon Web Services. Ele protege sites contra explorações web comuns, tráfego de bots e abuso automatizado. Muitos sites de alto tráfego, especialmente plataformas de e-commerce, serviços financeiros e aplicativos empresariais, usam o AWS WAF para restringir o acesso por trás de desafios CAPTCHA invisíveis.
Como o AWS WAF difere do reCAPTCHA ou Turnstile:
websiteURL para iniciar a solução.aws-waf-token. Isso deve ser enviado através do cabeçalho HTTP Cookie em solicitações subsequentes.awsKey, awsIv, awsContext, awsChallengeJS e outros parâmetros, dependendo da configuração do site. Estes são opcionais e necessários apenas para implementações específicas.
Não é o CloudFront. O AWS WAF é uma camada de firewall na frente de seu aplicativo web. O CloudFront é o CDN da Amazon. Um site pode usar o CloudFront sem o AWS WAF, ou o AWS WAF sem o CloudFront. Eles são serviços independentes, mas geralmente são usados juntos.
Antes de começarmos, certifique-se de ter o seguinte:
Importante: Certifique-se de que sua conta CapSolver tenha saldo suficiente. As tarefas de solução do AWS WAF consomem créditos com base no uso.
O CapSolver está disponível como uma integração oficial no n8n. Não há necessidade de instalar nenhum nó da comunidade. Você o encontrará diretamente no painel de nós ao construir seus fluxos de trabalho.
Como é uma integração oficial, você precisará criar uma credencial no n8n para que o nó CapSolver possa autenticar com sua conta.
Navegue até sua instância n8n e vá para Settings -> Credentials. Isso mostrará todas as credenciais que você configurou.

All (padrão)O n8n testará automaticamente a conexão. Você deverá ver um banner verde "Connection tested successfully" confirmando que sua chave de API é válida.

Importante: Cada nó CapSolver em seus fluxos de trabalho fará referência a esta credencial. Você só precisa criá-la uma vez. Todos os fluxos de trabalho de solução compartilharão a mesma credencial.
Agora você está pronto para construir seus fluxos de trabalho de solução do AWS WAF!
Antes de poder resolver um desafio do AWS WAF, você precisa confirmar que o site de destino está usando o AWS WAF e coletar quaisquer parâmetros opcionais. A maneira mais fácil de fazer isso é usando a extensão do navegador CapSolver combinada com inspeção manual.
Navegue até o site de destino e abra as DevTools (F12). Procure por estes sinais claros:
aws-waf-token na guia Aplicativocaptcha.awswaf.com ou URLs contendo challenge.jsx-amzn-waf-*A maioria das soluções do AWS WAF requer apenas o websiteURL. No entanto, alguns sites podem expor parâmetros adicionais que podem melhorar a precisão da solução.
| Parâmetro | Onde Procurar | Descrição |
|---|---|---|
awsKey |
Código-fonte da Página / Variável JS | O valor da chave retornado da página CAPTCHA |
awsIv |
Código-source da Página / Variável JS | O valor iv retornado da página CAPTCHA |
awsContext |
Código-source da Página / Variável JS | O valor do contexto retornado da página CAPTCHA |
awsChallengeJS |
Guia Rede | O URL de challenge.js (por exemplo, https://captcha.awswaf.com/.../challenge.js) |
awsApiJs |
Guia Rede | O URL de jsapi.js |
awsProblemUrl |
Guia Rede | O URL do endpoint do problema |
awsApiKey |
Guia Rede | O valor api_key do endpoint do problema |
awsExistingToken |
Cookies | O aws-waf-token anterior se estiver atualizando |
Dica: A maioria dos sites exigirá apenas o
websiteURL. Tente usar apenas esse parâmetro primeiro e adicione parâmetros opcionais apenas se o token não for aceito.
Para um guia mais detalhado sobre como identificar parâmetros CAPTCHA, consulte a documentação oficial do CapSolver.
Este fluxo de trabalho criará um endpoint de API POST que aceita parâmetros do AWS WAF e retorna o token de cookie resolvido.

O fluxo de trabalho consiste em quatro nós:
$json.error não está vazio){"error": "..."} se falhar| Configuração | Valor |
|---|---|
| Método HTTP | POST |
| Caminho | solver-aws-waf |
| Resposta | Response Node |
Isso criará um endpoint em https://your-n8n-instance.com/webhook/solver-aws-waf.
| Parâmetro | Valor | Descrição |
|---|---|---|
| Operação | AWS WAF |
Deve ser definido como AWS WAF |
| Tipo | AntiAwsWafTaskProxyLess |
Nenhum proxy necessário (padrão). Use AntiAwsWafTask com proxy para sites mais rigorosos |
| URL do Site | {{ $json.body.websiteURL }} |
O URL da página onde o desafio do AWS WAF está presente |
| awsKey | (Opcional) | O valor da chave retornado da página CAPTCHA |
| awsIv | (Opcional) | O valor iv retornado da página CAPTCHA |
| awsContext | (Opcional) | O valor do contexto retornado da página CAPTCHA |
| awsChallengeJS | (Opcional) | O link challenge.js |
| awsApiJs | (Opcional) | O link jsapi.js |
Principal diferença do Turnstile/reCAPTCHA: O AWS WAF não requer um
websiteKey. Apenas owebsiteURLé obrigatório. Certifique-se também de selecionar sua credencial CapSolver neste nó.
| Configuração | Valor |
|---|---|
| Condição | ={{ $json.error }} não está vazio |
| Ramo Verdadeiro | Encaminha para o nó Webhook de resposta de erro |
| Ramo Falso | Encaminha para o nó Webhook de resposta de sucesso |
Isso torna o caminho de erro explícito na tela. Como o nó CapSolver está configurado para continuar em caso de erro (onError: continueRegularOutput), as falhas chegarão aqui como {"error": "..."} em vez de travar o fluxo de trabalho.
Ramo de Sucesso (saída Falsa de Erro do CapSolver?):
| Configuração | Valor |
|---|---|
| Formato de Resposta | JSON |
| Corpo da Resposta | ={{ JSON.stringify($json.data) }} |
Ramo de Erro (saída Verdadeira de Erro do CapSolver?):
| Configuração | Valor |
|---|---|
| Formato de Resposta | JSON |
| Corpo da Resposta | ={{ JSON.stringify({ error: $json.error }) }} |
As mensagens de erro seguirão um dos dois formatos, dependendo do ponto de falha:
| Ponto de Falha | Formato |
|---|---|
| Criação da tarefa rejeitada (chave incorreta, saldo insuficiente, dados inválidos, etc.) | {"error": "Failed to create task: Request failed with status code 400"} |
| Tarefa criada, mas falhou ao resolver o CAPTCHA | {"error": "Solve failed: <reason>"} |
| Solução esgotou o tempo limite após 120 segundos | {"error": "Get task result timeout: unable to solve within 120000 seconds"} |
Nota: As falhas na criação da tarefa (chave de API incorreta, saldo zero, dados de tarefa inválidos) aparecerão como a mesma mensagem HTTP 400. O nó n8n captura a exceção HTTP antes de ler o corpo do erro do CapSolver.
Exemplos de Erros Comuns:
{"error": "Failed to create task: Request failed with status code 400"}
{"error": "Solve failed: Invalid parameters"}
{"error": "Get task result timeout: unable to solve within 120000 seconds"}
Envie uma solicitação POST para o seu endpoint Webhook:
curl -X POST https://your-n8n-instance.com/webhook/solver-aws-waf \
-H "Content-Type: application/json" \
-d '{
"websiteURL": "https://example.com/login"
}'
Resposta Esperada:
{
"taskId": "abc123...",
"solution": {
"cookie": "aws-waf-token=AQAAAA..."
},
"status": "ready"
}
Copie o JSON abaixo e importe-o para o seu n8n via Menu -> Import from JSON.
{
"name": "AWS WAF Solver API",
"nodes": [
{
"parameters": {
"content": "## API de Solução AWS WAF\n\n**Para:** Equipes que precisam resolver desafios do AWS WAF em outras ferramentas.\n\n**Função:** Aceita parâmetros do AWS WAF, envia o desafio para o CapSolver e retorna o cookie `aws-waf-token` resolvido.\n\n**Como Funciona:**\n1. O Webhook recebe uma solicitação POST com `websiteURL` e parâmetros opcionais.\n2. O CapSolver resolve o desafio do AWS WAF.\n3. Se bem-sucedido, o Webhook retorna uma resposta JSON com o cookie `aws-waf-token`.\n4. Se falhar, o Webhook retorna uma mensagem de erro.\n\n**Configuração:**\n1. Adicione sua chave de API do CapSolver em **Settings → Credentials**.\n2. Ative o fluxo de trabalho.\n3. Anote o URL do Webhook.\n\n**Importante:**\n- O AWS WAF não requer um `websiteKey`. Apenas o `websiteURL`.\n- A solução é um cookie `aws-waf-token`, que deve ser enviado como um cabeçalho HTTP `Cookie`.",
"height": 480,
"width": 460,
"color": 1
},
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"position": [
-728,
-400
],
"id": "sticky-blog-main-1773678228095-1",
"name": "Sticky Note"
},
{
"parameters": {
"httpMethod": "POST",
"path": "solver-aws-waf",
"responseMode": "responseNode",
"options": {}
},
"type": "n8n-nodes-base.webhook",
"typeVersion": 2.1,
"position": [
-400,
0
],
"id": "aw111111-1111-1111-1111-aw1111111101",
"name": "Webhook Trigger",
"webhookId": "aw111111-aaaa-bbbb-cccc-aw1111111101",
"onError": "continueRegularOutput"
},
{
"parameters": {
"operation": "AWS WAF",
"type": "AntiAwsWafTaskProxyLess",
"websiteURL": "={{ $json.body.websiteURL }}",
"awsKey": "={{ $json.body.awsKey }}",
"awsIv": "={{ $json.body.awsIv }}",
"awsContext": "={{ $json.body.awsContext }}",
"awsChallengeJS": "={{ $json.body.awsChallengeJS }}",
"awsApiJs": "={{ $json.body.awsApiJs }}",
"optional": {}
},
"type": "n8n-nodes-capsolver.capSolver",
"typeVersion": 1,
"position": [
-96,
0
],
"id": "aw111111-1111-1111-1111-aw1111111102",
"name": "Solve AWS WAF",
"credentials": {
"capSolverApi": {
"id": "YOUR_CREDENTIAL_ID",
"name": "CapSolver account"
}
}
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "aws-if-001",
"leftValue": "={{ $json.error }}",
"operator": {
"type": "string",
"operation": "isEmpty",
"singleValue": true
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.2,
"position": [
208,
0
],
"id": "aw111111-1111-1111-1111-aw1111111103",
"name": "CapSolver Error?"
},
{
"parameters": {
"respondWith": "json",
"responseBody": "={{ JSON.stringify($json.data) }}",
"options": {}
},
"type": "n8n-nodes-base.respondToWebhook",
"typeVersion": 1.5,
"position": [
512,
-80
],
"id": "aw111111-1111-1111-1111-aw1111111104",
"name": "Respond to Webhook (Success)"
},
{
"parameters": {
"respondWith": "json",
"responseBody": "={{ JSON.stringify({ error: $json.error }) }}",
"options": {}
},
"type": "n8n-nodes-base.respondToWebhook",
"typeVersion": 1.5,
"position": [
512,
128
],
"id": "aw111111-1111-1111-1111-aw1111111105",
"name": "Respond to Webhook (Error)"
}
],
"connections": {
"Webhook Trigger": {
"main": [
[
{
"node": "Solve AWS WAF",
"type": "main",
"index": 0
}
]
]
},
"Solve AWS WAF": {
"main": [
[
{
"node": "CapSolver Error?",
"type": "main",
"index": 0
}
]
]
},
"CapSolver Error?": {
"main": [
[
{
"node": "Respond to Webhook (Success)",
"type": "main",
"index": 0
}
],
[
{
"node": "Respond to Webhook (Error)",
"type": "main",
"index": 0
}
]
]
}
},
"active": false,
"settings": {
"executionOrder": "v1"
}
}
A API de solução e os exemplos de envio acima demonstram o padrão central para resolver desafios do AWS WAF, enviar cookies e processar os resultados. Os fluxos de trabalho abaixo estendem esse padrão para casos de uso prontos para produção. Cada um inclui gatilhos duplos (agendamento + webhook), rastreamento de estado persistente e saída estruturada.
| Fluxo de Trabalho | Objetivo |
|---|---|
Raspagem do AWS WAF — Detalhes de Preço e Produto — CapSolver + Agendamento + Webhook |
Raspa preços e nomes de produtos a cada 6 horas, compara com valores anteriores armazenados em staticData e alerta você sobre mudanças de preço |
Login de Conta do AWS WAF — CapSolver + Agendamento + Webhook |
Faz login em um site protegido pelo AWS WAF com sua conta. Primeiro resolve, depois POSTa as credenciais com o cookie |
Este fluxo de trabalho raspa uma página de produto a cada 6 horas (agendamento) ou sob demanda (webhook), extrai preços usando um nó HTML e os compara com valores armazenados anteriormente.
Caminho de Agendamento:
A cada 6 horas -> Resolver AWS WAF -> Buscar Página do Produto -> Extrair Dados
-> Comparar Dados -> Dados Alterados? -> Construir Alerta / Nenhuma Alteração
Comportamento chave:
Cookie (esta é a maneira correta de enviar o token do AWS WAF; não como um campo de formulário).product-price, h1)$workflow.staticData.lastPrice persiste o preço anterior entre as execuçõesdeal) quanto aumentos (gravidade: info){
"name": "AWS WAF Scraping — Price & Product Details — CapSolver + Schedule + Webhook",
"nodes": [
{
"parameters": {
"content": "## Raspagem do AWS WAF — Monitor de Preço e Produto\n\n**Para:** Equipes que precisam monitorar preços ou dados de produtos em sites protegidos pelo AWS WAF.\n\n**Função:** Resolve o AWS WAF, busca a página do produto, extrai preços e nomes via seletores CSS, compara com valores armazenados e alerta sobre mudanças se houver.\n\n**Como Funciona:**\n1. Um Agendamento (a cada 6 horas) ou Webhook dispara o fluxo.\n2. O CapSolver resolve o desafio do AWS WAF.\n3. Uma solicitação HTTP busca a página do produto com o token resolvido.\n4. Um nó HTML extrai preços e nomes de produtos.\n5. Um nó de Código compara o preço atual com o preço armazenado → alerta sobre mudanças se houver.\n\n**Configuração:**\n1. Adicione sua chave de API do CapSolver em **Settings → Credentials**.\n2. Substitua o URL do placeholder e a chave do site.\n3. Atualize os seletores CSS em \"Extrair Dados\" para corresponder à sua página de destino.\n4. Conecte a saída de \"Construir Alerta\" ao seu canal de notificação.",
"height": 560,
"width": 460,
"color": 1
},
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"position": [
-920,
-380
],
"id": "sticky-blog-main-1773678228094-1",
"name": "Sticky Note"
},
{
"parameters": {
"content": "### Caminho de Agendamento\nExecutado automaticamente a cada 6 horas.\nOs resultados são armazenados em dados estáticos do fluxo de trabalho para comparação entre execuções.",
"height": 480,
"width": 1900,
"color": 6
},
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"position": [
-440,
-280
],
"id": "sticky-blog-section-1773678228094-2",
"name": "Sticky Note1"
},
{
"parameters": {
"content": "### Caminho do Webhook\nDisparador sob demanda — mesma lógica, retorna resultados como uma resposta JSON.",
"height": 480,
"width": 1900,
"color": 6
},
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"position": [
-440,
140
],
"id": "sticky-blog-section-1773678228094-3",
"name": "Sticky Note2"
},
{
"parameters": {
"rule": {
"interval": [
{
"field": "hours",
"hoursInterval": 6
}
]
}
},
"type": "n8n-nodes-base.scheduleTrigger",
"typeVersion": 1.3,
"position": [
-400,
0
],
"id": "aw333333-3333-3333-3333-aw3333333301",
"name": "Every 6 Hours"
},
{
"parameters": {
"operation": "AWS WAF",
"type": "AntiAwsWafTaskProxyLess",
"websiteURL": "https://YOUR-TARGET-SITE.com/product-page",
"optional": {}
},
"type": "n8n-nodes-capsolver.capSolver",
"typeVersion": 1,
"position": [
-96,
0
],
"id": "aw333333-3333-3333-3333-aw3333333302",
"name": "Solve AWS WAF",
"credentials": {
"capSolverApi": {
"id": "YOUR_CREDENTIAL_ID",
"name": "CapSolver account"
}
}
},
{
"parameters": {
"url": "https://YOUR-TARGET-SITE.com/product-page",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "user-agent",
"value": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36"
},
{
"name": "Cookie",
"value": "={{ $json.data.solution.cookie }}"
}
]
},
"options": {
"response": {
"response": {
"fullResponse": false
}
}
}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.3,
"position": [
208,
0
],
"id": "aw333333-3333-3333-3333-aw3333333303",
"name": "Fetch Product Page"
},
{
"parameters": {
"operation": "extractHtmlContent",
"sourceData": "json",
"dataPropertyName": "data",
"extractionValues": {
"values": [
{
"key": "price",
"cssSelector": ".product-price, [data-price], .price",
"returnValue": "text",
"returnArray": false
},
{
"key": "productName",
"cssSelector": "h1, .product-title",
"returnValue": "text",
"returnArray": false
}
]
},
"options": {}
},
"type": "n8n-nodes-base.html",
"typeVersion": 1.2,
"position": [
512,
0
],
"id": "aw333333-3333-3333-3333-aw3333333304",
"name": "Extract Data"
},
{
"parameters": {
"jsCode": "// Get current and previous price from workflow static data\nconst staticData = $workflow.staticData;\nconst currentPrice = $input.first().json.price;\nconst previousPrice = staticData.lastPrice;\nconst productName = $input.first().json.productName || 'Product';\n\n// Parse numeric values for comparison\nconst parsePrice = (str) => {\n if (!str) return null;\n const match = str.match(/[\\d,]+\\.?\\d*/);\n return match ? parseFloat(match[0].replace(',', '')) : null;\n};\n\nconst currentNum = parsePrice(currentPrice);\nconst previousNum = parsePrice(previousPrice);\n\n// Update stored price\nstaticData.lastPrice = currentPrice;\nstaticData.lastChecked = new Date().toISOString();\n\nconst changed = previousNum !== null && currentNum !== null && currentNum !== previousNum;\nconst direction = changed ? (currentNum < previousNum ? 'dropped' : 'increased') : 'unchanged';\nconst diff = changed ? Math.abs(currentNum - previousNum).toFixed(2) : '0';\n\nreturn [{\n json: {\n productName,\n currentPrice,\n previousPrice: previousPrice || 'first check',\n changed,\n direction,\n diff: changed ? `$${diff}` : null,\n checkedAt: new Date().toISOString()\n }\n}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
800,
0
],
"id": "aw333333-3333-3333-3333-aw3333333305",
"name": "Compare Data"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "price-if-001",
"leftValue": "={{ $json.changed }}",
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.2,
"position": [
1104,
0
],
"id": "aw333333-3333-3333-3333-aw3333333306",
"name": "Data Changed?"
},
{
"parameters": {
"assignments": {
"assignments": [
{
"id": "alert-001",
"name": "alert",
"value": "=Price {{ $json.direction }} for {{ $json.productName }}: {{ $json.previousPrice }} → {{ $json.currentPrice }} ({{ $json.direction === 'dropped' ? '-' : '+' }}{{ $json.diff }})",
"type": "string"
},
{
"id": "alert-002",
"name": "severity",
"value": "={{ $json.direction === 'dropped' ? 'deal' : 'info' }}",
"type": "string"
},
{
"id": "alert-003",
"name": "checkedAt",
"value": "={{ $json.checkedAt }}",
"type": "string"
}
]
},
"options": {}
},
"type": "n8n-nodes-base.set",
"typeVersion": 3.4,
"position": [
1408,
-80
],
"id": "aw333333-3333-3333-3333-aw3333333307",
"name": "Build Alert"
},
{
"parameters": {
"assignments": {
"assignments": [
{
"id": "nc-001",
"name": "status",
"value": "no_change",
"type": "string"
},
{
"id": "nc-002",
"name": "currentPrice",
"value": "={{ $json.currentPrice }}",
"type": "string"
},
{
"id": "nc-003",
"name": "checkedAt",
"value": "={{ $json.checkedAt }}",
"type": "string"
}
]
},
"options": {}
},
"type": "n8n-nodes-base.set",
"typeVersion": 3.4,
"position": [
1408,
128
],
"id": "aw333333-3333-3333-3333-aw3333333308",
"name": "No Change"
},
{
"parameters": {
"httpMethod": "POST",
"path": "price-monitor-aws-waf",
"responseMode": "responseNode",
"options": {}
},
"type": "n8n-nodes-base.webhook",
"typeVersion": 2.1,
"position": [
-400,
420
],
"id": "aw333333-3333-3333-3333-aw3333333309",
"name": "Webhook Trigger",
"webhookId": "aw333333-aaaa-bbbb-cccc-aw3333333309",
"onError": "continueRegularOutput"
},
{
"parameters": {
"operation": "AWS WAF",
"type": "AntiAwsWafTaskProxyLess",
"websiteURL": "https://YOUR-TARGET-SITE.com/product-page",
"optional": {}
},
"type": "n8n-nodes-capsolver.capSolver",
"typeVersion": 1,
"position": [
-96,
420
],
"id": "aw333333-3333-3333-3333-aw3333333310",
"name": "Solve AWS WAF [Webhook]",
"credentials": {
"capSolverApi": {
"id": "YOUR_CREDENTIAL_ID",
"name": "CapSolver account"
}
}
},
{
"parameters": {
"url": "https://YOUR-TARGET-SITE.com/product-page",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "user-agent",
"value": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36"
},
{
"name": "Cookie",
"value": "={{ $json.data.solution.cookie }}"
}
]
},
"options": {
"response": {
"response": {
"fullResponse": false
}
}
}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.3,
"position": [
208,
420
],
"id": "aw333333-3333-3333-3333-aw3333333311",
"name": "Fetch Product Page [Webhook]"
},
{
"parameters": {
"operation": "extractHtmlContent",
"sourceData": "json",
"dataPropertyName": "data",
"extractionValues": {
"values": [
{
"key": "price",
"cssSelector": ".product-price, [data-price], .price",
"returnValue": "text",
"returnArray": false
},
{
"key": "productName",
"cssSelector": "h1, .product-title",
"returnValue": "text",
"returnArray": false
}
]
},
"options": {}
},
"type": "n8n-nodes-base.html",
"typeVersion": 1.2,
"position": [
512,
420
],
"id": "aw333333-3333-3333-3333-aw3333333312",
"name": "Extract Data [Webhook]"
},
{
"parameters": {
"jsCode": "// Get current and previous price from workflow static data\nconst staticData = $workflow.staticData;\nconst currentPrice = $input.first().json.price;\nconst previousPrice = staticData.lastPrice;\nconst productName = $input.first().json.productName || 'Product';\n\n// Parse numeric values for comparison\nconst parsePrice = (str) => {\n if (!str) return null;\n const match = str.match(/[\\d,]+\\.?\\d*/);\n return match ? parseFloat(match[0].replace(',', '')) : null;\n};\n\nconst currentNum = parsePrice(currentPrice);\nconst previousNum = parsePrice(previousPrice);\n\n// Update stored price\nstaticData.lastPrice = currentPrice;\nstaticData.lastChecked = new Date().toISOString();\n\nconst changed = previousNum !== null && currentNum !== null && currentNum !== previousNum;\nconst direction = changed ? (currentNum < previousNum ? 'dropped' : 'increased') : 'unchanged';\nconst diff = changed ? Math.abs(currentNum - previousNum).toFixed(2) : '0';\n\nreturn [{\n json: {\n productName,\n currentPrice,\n previousPrice: previousPrice || 'first check',\n changed,\n direction,\n diff: changed ? `$${diff}` : null,\n checkedAt: new Date().toISOString()\n }\n}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
800,
420
],
"id": "aw333333-3333-3333-3333-aw3333333313",
"name": "Compare Data [Webhook]"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "price-if-002",
"leftValue": "={{ $json.changed }}",
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.2,
"position": [
1104,
420
],
"id": "aw333333-3333-3333-3333-aw3333333314",
"name": "Data Changed? [Webhook]"
},
{
"parameters": {
"assignments": {
"assignments": [
{
"id": "alert-004",
"name": "alert",
"value": "=Price {{ $json.direction }} for {{ $json.productName }}: {{ $json.previousPrice }} → {{ $json.currentPrice }} ({{ $json.direction === 'dropped' ? '-' : '+' }}{{ $json.diff }})",
"type": "string"
},
{
"id": "alert-005",
"name": "severity",
"value": "={{ $json.direction === 'dropped' ? 'deal' : 'info' }}",
"type": "string"
},
{
"id": "alert-006",
"name": "checkedAt",
"value": "={{ $json.checkedAt }}",
"type": "string"
}
]
},
"options": {}
},
"type": "n8n-nodes-base.set",
"typeVersion": 3.4,
"position": [
1408,
340
],
"id": "aw333333-3333-3333-3333-aw3333333315",
"name": "Build Alert [Webhook]"
},
{
"parameters": {
"assignments": {
"assignments": [
{
"id": "nc-004",
"name": "status",
"value": "no_change",
"type": "string"
},
{
"id": "nc-005",
"name": "currentPrice",
"value": "={{ $json.currentPrice }}",
"type": "string"
},
{
"id": "nc-006",
"name": "checkedAt",
"value": "={{ $json.checkedAt }}",
"type": "string"
}
]
},
"options": {}
},
"type": "n8n-nodes-base.set",
"typeVersion": 3.4,
"position": [
1408,
548
],
"id": "aw333333-3333-3333-3333-aw3333333316",
"name": "No Change [Webhook]"
},
{
"parameters": {
"respondWith": "json",
"responseBody": "={{ JSON.stringify($json) }}",
"options": {}
},
"type": "n8n-nodes-base.respondToWebhook",
"typeVersion": 1.5,
"position": [
1712,
420
],
"id": "aw333333-3333-3333-3333-aw3333333317",
"name": "Respond to Webhook [Webhook]"
}
],
"connections": {
"Every 6 Hours": {
"main": [
[
{
"node": "Solve AWS WAF",
"type": "main",
"index": 0
}
]
]
},
"Solve AWS WAF": {
"main": [
[
{
"node": "Fetch Product Page",
"type": "main",
"index": 0
}
]
]
},
"Fetch Product Page": {
"main": [
[
{
"node": "Extract Data",
"type": "main",
"index": 0
}
]
]
},
"Extract Data": {
"main": [
[
{
"node": "Compare Data",
"type": "main",
"index": 0
}
]
]
},
"Compare Data": {
"main": [
[
{
"node": "Data Changed?",
"type": "main",
"index": 0
}
]
]
},
"Data Changed?": {
"main": [
[
{
"node": "Build Alert",
"type": "main",
"index": 0
}
],
[
{
"node": "No Change",
"type": "main",
"index": 0
}
]
]
},
"Webhook Trigger": {
"main": [
[
{
"node": "Solve AWS WAF [Webhook]",
"type": "main",
"index": 0
}
]
]
},
"Solve AWS WAF [Webhook]": {
"main": [
[
{
"node": "Fetch Product Page [Webhook]",
"type": "main",
"index": 0
}
]
]
},
"Fetch Product Page [Webhook]": {
"main": [
[
{
"node": "Extract Data [Webhook]",
"type": "main",
"index": 0
}
]
]
},
"Extract Data [Webhook]": {
"main": [
[
{
"node": "Compare Data [Webhook]",
"type": "main",
"index": 0
}
]
]
},
"Compare Data [Webhook]": {
"main": [
[
{
"node": "Data Changed? [Webhook]",
"type": "main",
"index": 0
}
]
]
},
"Data Changed? [Webhook]": {
"main": [
[
{
"node": "Build Alert [Webhook]",
"type": "main",
"index": 0
}
],
[
{
"node": "No Change [Webhook]",
"type": "main",
"index": 0
}
]
]
},
"Build Alert [Webhook]": {
"main": [
[
{
"node": "Respond to Webhook [Webhook]",
"type": "main",
"index": 0
}
]
]
},
"No Change [Webhook]": {
"main": [
[
{
"node": "Respond to Webhook [Webhook]",
"type": "main",
"index": 0
}
]
]
}
},
"active": false,
"settings": {
"executionOrder": "v1"
}
}
Este fluxo de trabalho automatiza o envio de um formulário de login protegido pelo AWS WAF do início ao fim. Ele resolve o desafio do AWS WAF antes de enviar as credenciais.
Este fluxo de trabalho consiste em cinco nós:
| Configuração | Valor |
|---|---|
| Método HTTP | POST |
| Caminho | login-aws-waf |
| Resposta | Response Node |
Isso criará um endpoint em https://your-n8n-instance.com/webhook/login-aws-waf.
| Parâmetro | Valor |
|---|---|
| Operação | AWS WAF |
| URL do Site | https://YOUR-TARGET-SITE.com/login |
Certifique-se também de selecionar sua credencial CapSolver.
| Configuração | Valor |
|---|---|
| Método | POST |
| URL | https://YOUR-TARGET-SITE.com/login |
| Tipo de Conteúdo | form-urlencoded |
| Parâmetros do Corpo | username=YOUR_USERNAME, password=YOUR_PASSWORD, Cookie={{ $('Solve AWS WAF').item.json.data.solution.cookie }} |
Importante: Substitua
YOUR_USERNAMEeYOUR_PASSWORDpelas suas credenciais reais. Além disso, você pode precisar ajustar os nomes dos campos do formulário para corresponder ao HTML do seu site de destino.
| Configuração | Valor |
|---|---|
| Formato de Resposta | JSON |
| Corpo da Resposta | ={{ JSON.stringify($json) }} |
Envie uma solicitação POST para o seu endpoint Webhook:
curl -X POST https://your-n8n-instance.com/webhook/login-aws-waf \
-H "Content-Type: application/json" \
-d '{
"websiteURL": "https://example.com/login",
"username": "testuser",
"password": "testpass"
}'
Resposta Esperada (Sucesso):
{
"status": "success",
"message": "Login successful",
"solution": {
"cookie": "aws-waf-token=AQAAAA..."
}
}
Resposta Esperada (Falha):
{
"status": "failed",
"message": "Login failed: Invalid credentials or captcha",
"error": "..."
}
Copie o JSON abaixo e importe-o para o seu n8n via Menu -> Import from JSON.
{
"name": "AWS WAF Account Login — CapSolver + Schedule + Webhook",
"nodes": [
{
"parameters": {
"content": "## Automação de Login de Conta do AWS WAF — CapSolver + Agendamento + Webhook\n\n**Para:** Equipes que precisam automatizar o login em contas protegidas pelo AWS WAF.\n\n**Função:** Resolve o desafio do AWS WAF e envia o formulário de login com o cookie resolvido e as credenciais do usuário.\n\n**Como Funciona:**\n1. O Webhook dispara o fluxo.\n2. O CapSolver resolve o desafio do AWS WAF.\n3. Uma solicitação HTTP envia o formulário de login com o cookie resolvido e as credenciais do usuário.\n4. O Webhook retorna o resultado do login.\n\n**Configuração:**\n1. Adicione sua chave de API do CapSolver em **Settings → Credentials**.\n2. Substitua o URL do placeholder e as credenciais.\n3. Ajuste os nomes dos campos do formulário para corresponder ao seu site de destino.\n4. Ative o fluxo de trabalho.",
"height": 480,
"width": 460,
"color": 1
},
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"position": [
-728,
-400
],
"id": "sticky-blog-main-1773678228096-1",
"name": "Sticky Note"
},
{
"parameters": {
"httpMethod": "POST",
"path": "login-aws-waf",
"responseMode": "responseNode",
"options": {}
},
"type": "n8n-nodes-base.webhook",
"typeVersion": 2.1,
"position": [
-400,
0
],
"id": "aw444444-4444-4444-4444-aw4444444401",
"name": "Webhook Trigger",
"webhookId": "aw444444-aaaa-bbbb-cccc-aw4444444401",
"onError": "continueRegularOutput"
},
{
"parameters": {
"operation": "AWS WAF",
"type": "AntiAwsWafTaskProxyLess",
"websiteURL": "={{ $json.body.websiteURL }}",
"optional": {}
},
"type": "n8n-nodes-capsolver.capSolver",
"typeVersion": 1,
"position": [
-96,
0
],
"id": "aw444444-4444-4444-4444-aw4444444402",
"name": "Solve AWS WAF",
"credentials": {
"capSolverApi": {
"id": "YOUR_CREDENTIAL_ID",
"name": "CapSolver account"
}
}
},
{
"parameters": {
"method": "POST",
"url": "={{ $json.body.websiteURL }}",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "user-agent",
"value": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36"
},
{
"name": "Content-Type",
"value": "application/x-www-form-urlencoded"
},
{
"name": "Cookie",
"value": "={{ $('Solve AWS WAF').item.json.data.solution.cookie }}"
}
]
},
"sendBody": true,
"contentType": "form-urlencoded",
"bodyParameters": {
"parameters": [
{
"name": "username",
"value": "={{ $json.body.username }}"
},
{
"name": "password",
"value": "={{ $json.body.password }}"
}
]
},
"options": {
"response": {
"response": {
"fullResponse": false
}
}
}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.3,
"position": [
208,
0
],
"id": "aw444444-4444-4444-4444-aw4444444403",
"name": "Submit Login Form"
},
{
"parameters": {
"respondWith": "json",
"responseBody": "={{ JSON.stringify($json) }}",
"options": {}
},
"type": "n8n-nodes-base.respondToWebhook",
"typeVersion": 1.5,
"position": [
512,
0
],
"id": "aw444444-4444-4444-4444-aw4444444404",
"name": "Respond to Webhook"
}
],
"connections": {
"Webhook Trigger": {
"main": [
[
{
"node": "Solve AWS WAF",
"type": "main",
"index": 0
}
]
]
},
"Solve AWS WAF": {
"main": [
[
{
"node": "Submit Login Form",
"type": "main",
"index": 0
}
]
]
},
"Submit Login Form": {
"main": [
[
{
"node": "Respond to Webhook",
"type": "main",
"index": 0
}
]
]
}
},
"active": false,
"settings": {
"executionOrder": "v1"
}
}
Este erro indica que sua conta ou plano CapSolver não inclui acesso ao AWS WAF. Verifique seu Painel CapSolver para confirmar se este serviço está incluído em seu plano.
Este erro indica que o parâmetro websiteURL que você forneceu no nó CapSolver está incorreto. Verifique novamente a guia de rede das ferramentas de desenvolvedor do seu site de destino para garantir que você está usando o valor correto.
Se o login falhar mesmo com o AWS WAF resolvido com sucesso, o problema pode estar nos seguintes pontos:
Este erro indica que a chave de API do CapSolver que você configurou no n8n está incorreta ou expirou. Verifique seu Painel CapSolver e atualize as credenciais no n8n.
websiteURL e quaisquer parâmetros opcionais como awsKey, awsIv, awsContext, awsChallengeJS e awsApiJs estão corretos. Estes são cruciais para uma solução bem-sucedida do AWS WAF.Pronto para começar? Inscreva-se no CapSolver e use o código bônus n8n para obter um bônus extra de 8% em sua primeira recarga!

O AWS WAF é um firewall de aplicativo web de nível empresarial da Amazon que protege sites contra tráfego de bots e abuso por meio de desafios invisíveis e verificação baseada em token.
O AWS WAF não requer uma chave de site, usa autenticação baseada em cookie, retorna um cookie aws-waf-token e geralmente é um desafio invisível sem widgets visíveis para interação do usuário.
Os preços variam de acordo com o uso. Verifique a página de preços do CapSolver para os preços atuais do AWS WAF. As tarefas de solução do AWS WAF são mais caras do que o reconhecimento simples de imagem para texto, mas mais baratas do que outros tipos complexos de CAPTCHA.
As tarefas de solução do AWS WAF geralmente levam de 10 a 30 segundos, dependendo da complexidade do desafio e da carga do servidor CapSolver. Ao contrário do ImageToTextTask, a solução do AWS WAF envolve a criação e o polling de tarefas, portanto, não é instantânea.
O serviço de solução do AWS WAF do CapSolver geralmente não exige que você forneça um proxy. O CapSolver lida com os requisitos de proxy internamente. Você só precisa fornecer o websiteURL e quaisquer parâmetros opcionais.
aws-waf-token não está sendo aceito?Se o seu aws-waf-token não estiver sendo aceito, verifique o seguinte:
awsKey, awsIv, etc., certifique-se de fornecê-los corretamente.Se o login falhar mesmo com o AWS WAF resolvido com sucesso, verifique o seguinte:
Sim. Este fluxo de trabalho funciona tanto com o n8n auto-hospedado quanto com o n8n Cloud. O nó CapSolver já está disponível como uma integração oficial. Você só precisa adicionar suas credenciais de API.
Aprenda arquitetura de raspagem web escalável em Rust com reqwest, scraper, raspagem assíncrona, raspagem de navegador headless, rotação de proxies e tratamento de CAPTCHA compatível.

Compare o Selenium vs Puppeteer para resolver CAPTCHA. Descubra benchmarks de desempenho, notas de estabilidade e como integrar o CapSolver para o máximo de sucesso.
