如何使用NodeJS解决AWS验证码

Ethan Collins
Pattern Recognition Specialist
03-Nov-2025

在现代的网络环境中,保护在线资源免受自动化威胁至关重要。AWS Web Application Firewall (WAF) 是一个强大的安全层,通常会部署挑战或托管验证码来过滤恶意机器人。虽然对安全有效,但这些机制对合法的自动化任务(如网页爬取、监控或测试)构成了重大障碍。
本全面指南使用 Node.js 和 CapSolver 服务提供了一个强大的自动化解决方案。我们将逐步介绍如何设置环境、实现模块化的 Node.js 脚本,并利用 CapSolver 的专用 AntiAwsWafTask 来绕过 WAF 挑战(HTTP 202)和 WAF 验证码(HTTP 405)场景。在本教程结束时,您将拥有一个可直接投入生产的脚本,能够获取访问受保护内容所需的 aws-waf-token cookie。
⚙️ 前提条件
在开始之前,请确保准备好以下环境和信息:
- Node.js 环境:您的系统上已安装 Node.js(推荐使用 LTS 版本)。
- CapSolver API 密钥:您需要一个 CapSolver 账户和您的 API 密钥。
- 代理(可选):如果目标网站有地理限制或您需要隐藏真实 IP,请准备一个 HTTP/HTTPS 代理。
🛠️ 第一步:安装必要的依赖
在您的项目目录中,执行以下命令以安装所需的 Node.js 模块:
bash
npm install axios cheerio
axios:用于发送 HTTP 请求。cheerio:用于解析 HTML 内容并提取 AWS WAF 挑战所需的参数。
💻 第二步:Node.js 核心代码实现
以下是用于解决 AWS WAF 挑战和验证码的 Node.js 脚本。它会自动检测网站返回的状态码,并根据需要执行相应的 CapSolver 任务。
请将以下代码保存为 aws_waf_solver.js。
javascript
const axios = require('axios');
const cheerio = require('cheerio');
const { URL } = require('url');
// ⚠️ 配置:请替换为您的实际值
const CLIENT_KEY = "YOUR_CAPSOLVER_API_KEY"; // 替换为您的 CapSolver API 密钥
const PAGE_URL = "https://norway-meetup.aws.wslab.no/"; // 替换为目标网站 URL
const PROXY = "YOUR_PROXY_ADDRESS"; // 替换为您的代理地址(格式:user:pass@ip:port 或 ip:port)
// --- 辅助函数 ---
/**
* 暂停执行指定的毫秒数
* @param {number} ms 毫秒数
*/
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
/**
* 创建 CapSolver 任务
* @param {object} payload 任务负载
* @returns {Promise<object>} 任务创建结果
*/
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(`CapSolver API 错误: ${res.data.errorDescription}`);
}
return res.data;
} catch (error) {
console.error("创建 CapSolver 任务失败:", error.message);
return null;
}
}
/**
* 获取 CapSolver 任务结果,直到任务完成
* @param {string} taskId 任务 ID
* @returns {Promise<object>} 任务结果
*/
async function getTaskResult(taskId) {
if (!taskId) return null;
console.log(`等待任务结果(ID: ${taskId})...`);
try {
let success = false;
let result = null;
while (!success) {
await sleep(3000); // 每 3 秒查询一次
const res = await axios.post('https://api.capsolver.com/getTaskResult', {
clientKey: CLIENT_KEY,
taskId: taskId
});
if (res.data.errorId !== 0) {
throw new Error(`CapSolver API 错误: ${res.data.errorDescription}`);
}
if (res.data.status === "ready") {
success = true;
result = res.data;
console.log("任务完成,已获得解决方案。");
} else if (res.data.status === "processing") {
console.log("任务仍在处理中...");
}
}
return result;
} catch (error) {
console.error("获取 CapSolver 任务结果失败:", error.message);
return null;
}
}
// --- 核心求解函数 ---
/**
* 解决 AWS WAF 挑战(状态码 202)
* @param {string} awsChallengeJS AWS 挑战 JavaScript URL
* @returns {Promise<string|null>} 解决后的 AWS WAF Cookie 值
*/
async function solveAwsChallenge(awsChallengeJS) {
console.log("检测到 AWS WAF 挑战(状态码 202),开始求解...");
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;
}
/**
* 解决 AWS WAF 验证码 + 挑战(状态码 405)
* @param {string} htmlContent 包含验证码参数的 HTML 内容
* @param {string} awsChallengeJS AWS 挑战 JavaScript URL
* @returns {Promise<string|null>} 解决后的 AWS WAF Cookie 值
*/
async function solveAwsCaptchaChallenge(htmlContent, awsChallengeJS) {
console.log("检测到 AWS WAF 验证码(状态码 405),开始求解...");
const $ = cheerio.load(htmlContent);
const scriptContent = $("script[type='text/javascript']").last().html();
if (!scriptContent) {
console.error("无法找到包含验证码参数的脚本内容。");
return null;
}
// 使用正则表达式提取关键参数
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("从脚本中未能提取所有必需的验证码参数(key, iv, context)。");
return null;
}
console.log(`提取的参数: Key=${key}, IV=${iv}, Context=${context}`);
const taskPayload = {
type: "AntiAwsWafTask", // CapSolver 统一使用此任务类型
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;
}
/**
* 主执行函数
*/
async function main() {
let awsWafCookie = null;
let initialResponse = null;
// 1. 初始请求目标页面
try {
console.log(`请求目标页面: ${PAGE_URL}`);
initialResponse = 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",
"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"
},
// 允许处理 2xx、3xx、4xx 状态码
validateStatus: (status) => status >= 200 && status < 500
});
console.log(`初始响应状态码: ${initialResponse.status}`);
} catch (error) {
console.error(`初始请求失败: ${error.message}`);
return;
}
const $ = cheerio.load(initialResponse.data);
const scriptTags = $('script[src*="token.awswaf.com"]');
const awsChallengeJS = scriptTags.attr('src');
if (!awsChallengeJS) {
console.log("未检测到 AWS WAF 挑战脚本。该网站可能未受保护或已通过验证。");
// 如果没有挑战脚本,直接使用初始响应
if (initialResponse.status === 200) {
console.log("网站加载成功。");
// console.log(initialResponse.data); // 打印最终内容
return;
}
} else {
console.log(`检测到 AWS WAF 挑战脚本 URL: ${awsChallengeJS}`);
}
// 2. 根据状态码确定并解决挑战/验证码
if (initialResponse.status === 202) {
// 仅 AWS WAF 挑战
awsWafCookie = await solveAwsChallenge(awsChallengeJS);
} else if (initialResponse.status === 405) {
// AWS WAF 验证码 + 挑战
awsWafCookie = await solveAwsCaptchaChallenge(initialResponse.data, awsChallengeJS);
} else if (initialResponse.status === 200) {
console.log("网站加载成功,无需验证码求解。");
// console.log(initialResponse.data); // 打印最终内容
return;
} else {
console.log(`遇到未处理的状态码: ${initialResponse.status}。`);
return;
}
// 3. 使用获取的 Cookie 再次请求目标页面
if (awsWafCookie) {
try {
console.log("\n--- 第二次请求:使用 AWS WAF Cookie ---");
console.log(`使用的 Cookie: ${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 // 期望最终成功
});
console.log(`最终响应状态码: ${finalResponse.status}`);
console.log("成功获取网站内容!");
// console.log(finalResponse.data); // 打印最终内容
} catch (error) {
console.error(`最终请求失败: ${error.message}`);
}
} else {
console.log("未能获取 AWS WAF Cookie,无法执行第二次请求。");
}
}
main();
💡 关键点总结
| 关键点 | 原始代码问题 | 优化改进 |
|---|---|---|
| 依赖安装 | 缺少 cheerio,使用了错误的 Python 语法高亮。 |
明确说明需要安装 axios 和 cheerio,使用正确的 bash 语法高亮。 |
| 任务类型 | 混合使用 FunCaptchaTaskProxyless 和 AntiAwsWafTask。 |
统一使用 CapSolver 官方推荐的 AntiAwsWafTask 处理所有 AWS WAF 场景。 |
| 参数提取 | 405 逻辑中提取 awsChallengeJS 的逻辑不完整,202 逻辑中未提取。 |
在 main 函数中统一提取 awsChallengeJS,并根据状态码调用不同的求解函数(202 或 405)。 |
| 错误处理 | 简单的错误处理,缺乏 API 错误检查和任务等待提示。 | 在 createTask 和 getTaskResult 中添加 CapSolver API 错误检查(errorId !== 0),并在任务处理期间提供状态提示。 |
| 代码结构 | 所有逻辑集中在 main 函数中,可读性差。 |
分离为清晰的辅助函数(sleep、createTask、getTaskResult)和核心求解函数(solveAwsChallenge、solveAwsCaptchaChallenge),使逻辑更清晰。 |
| 请求头 | 原始请求头冗余且不完整。 | 简化并使用更标准的浏览器模拟请求头。 |
❓ 常见问题(FAQ)
问:为什么需要处理 HTTP 202 和 HTTP 405 状态码?
答: AWS WAF 使用不同的安全措施,导致不同的 HTTP 状态码:
- HTTP 202(已接受):通常表示需要 WAF 挑战。这是一种较轻量的安全检查,通常涉及运行 JavaScript 代码。
- HTTP 405(方法不允许):通常表示需要 WAF 验证码,这是一种更复杂的检查,涉及解决视觉或交互式谜题,同时需要挑战参数。我们的脚本设计为能自动检测并处理这两种情况。
问:可以不使用代理使用此脚本吗?
答: 可以。PROXY 变量是可选的。如果您不需要代理,可以在配置中将 const PROXY = "";。然而,对于网页爬取和自动化任务,使用高质量的代理是非常推荐的,以避免 IP 被封禁并确保稳定的访问。
问:什么是 AntiAwsWafTask?
答: AntiAwsWafTask 是 CapSolver 提供的一种专用任务类型,专门用于处理 AWS WAF 安全机制。它智能地处理从受保护页面提取的挑战参数(包括 awsKey、awsIv、awsContext 和 awsChallengeJS),并返回绕过保护所需的 aws-waf-token cookie。
📚 更多信息
- CapSolver AWS WAF 官方文档: https://docs.capsolver.com/en/guide/captcha/awsWaf/
- CapSolver API 文档: https://docs.capsolver.com/en/api/
✅ 结论
本指南展示了使用Node.js和**CapSolver**编程解决AWS WAF挑战和验证码的稳健且高效方法。通过实现模块化脚本并利用CapSolver的专业任务类型,您可以将此解决方案无缝集成到自动化工作流中。成功的关键在于正确识别WAF状态码(202或405),提取必要的参数,并将生成的aws-waf-token cookie用于后续请求。这种方法确保您的自动化任务可以可靠地访问受AWS WAF保护的内容。
合规声明: 本博客提供的信息仅供参考。CapSolver 致力于遵守所有适用的法律和法规。严禁以非法、欺诈或滥用活动使用 CapSolver 网络,任何此类行为将受到调查。我们的验证码解决方案在确保 100% 合规的同时,帮助解决公共数据爬取过程中的验证码难题。我们鼓励负责任地使用我们的服务。如需更多信息,请访问我们的服务条款和隐私政策。
更多

如何使用NodeJS解决AWS验证码
在本文中,我们将向您展示如何使用Node.JS解决AWS验证码/挑战。

Ethan Collins
03-Nov-2025

通过浏览器或API集成自动解决AWS WAF验证码
学习如何通过浏览器扩展和API集成自动解决亚马逊云服务WAF验证码。本指南涵盖图像识别、基于令牌的挑战以及CapSolver解决方案,实现无缝自动化和网络爬虫。

Emma Foster
23-Oct-2025

如何在Crawl4AI中通过CapSolver集成解决AWS WAF问题
学习如何在Crawl4AI中使用CapSolver的API和浏览器扩展集成方法来解决AWS WAF防护措施。本指南提供代码示例,用于实现无缝网络爬取。

Lucas Mitchell
21-Oct-2025

用于自动化和爬虫的最佳AWS WAF验证码破解工具
发现最佳的AWS WAF CAPTCHA求解器。CapSolver的AI驱动解决方案可即时绕过WAF挑战,确保大规模网络爬取和自动化的无缝进行

Ethan Collins
17-Oct-2025

