如何在网络抓取时解决亚马逊 (AWS WAF) CAPTCHA 和挑战
AWS WAF(亚马逊的服务)为网络资源提供了两种主要的保护类型,以防止不必要的自动化操作:
CAPTCHA – 要求用户解决任务,例如在特定字段中输入文本、移动滑块、选择图像中的某些对象或将元素拖动到指定位置。此外,还可能提供音频 CAPTCHA,用户必须听取并识别背景噪音中的单词,并将其输入到相应字段中。
Challenge – 在这种情况下,用户无需解决任何问题即可与网站互动 – 检查在后台进行,通过分析会话参数和请求行为(如请求频率、JavaScript 使用、鼠标行为以及是否存在 Cookies)。如果检查成功,用户可以继续使用网站。如果检查失败,请求可能会被阻止,或者显示 CAPTCHA 以进行额外验证。如果系统检测到自动化的迹象,它可能会提高验证级别,以确保安全性并保护网站免受未经授权的访问。
如何使用 CapMonster Cloud 解决亚马逊 CAPTCHA
亚马逊的安全系统经过精心设计,提供了高水平的安全性;它不断更新,以使机器人更难访问网站。然而,出于网站测试、安全抓取和调试的目的,可以使用云服务 CapMonster Cloud 解决此问题。
找到 CAPTCHA 数据
要解决这种类型的 CAPTCHA,需要访问带有 CAPTCHA 的目标网站,打开开发者工具,并提取必要的 CAPTCHA 数据,例如 websiteKey、context、iv 和 challengeScript。
以下是更详细的指南:
- 加载所需页面,打开开发者工具,导航到网络标签,找到具有 405 响应的文档行。
- 选择该文档并转到响应标签:
- 找到 window.gokuProps 对象,其中包含所有必要的参数。
所需参数及其值的表格:
参数 | 类型 | 是否必需 | 值 |
---|---|---|---|
type | 字符串 | 是 | AmazonTaskProxyless |
websiteURL | 字符串 | 是 | 解决 CAPTCHA 的主页面 URL |
challengeScript | 字符串 | 是 | challenge.js 的链接 |
captchaScript | 字符串 | 是 | captcha.js 的链接 |
websiteKey | 字符串 | 是 | 可以从 CAPTCHA 的 HTML 页面获得,或通过执行 window.gokuProps.key 在 JavaScript 中获得 |
context | 字符串 | 是 | 可以从 CAPTCHA 的 HTML 页面获得,或通过执行 window.gokuProps.context 在 JavaScript 中获得 |
iv | 字符串 | 是 | 可以从 CAPTCHA 的 HTML 页面获得,或通过执行 window.gokuProps.iv 在 JavaScript 中获得 |
cookieSolution | 布尔值 | 否 | 默认为 false。如果需要 "aws-waf-token" Cookies,请设置为 true。否则,响应将包含 "captcha_voucher" 和 "existing_token" |
您还可以使用以下 JavaScript 代码自动获取 AWS WAF CAPTCHA 的参数:
// 提取 CAPTCHA 参数
var gokuProps = window.gokuProps;
var websiteKey = gokuProps ? gokuProps.key : "未找到";
var context = gokuProps ? gokuProps.context : "未找到";
var iv = gokuProps ? gokuProps.iv : "未找到";
// 提取 CAPTCHA 脚本 URL
var scripts = Array.from(document.querySelectorAll('script'));
var challengeScriptUrl = scripts.find(script => script.src.includes('challenge.js'))?.src || "未找到";
var captchaScriptUrl = scripts.find(script => script.src.includes('captcha.js'))?.src || "未找到";
// 输出参数和脚本 URL
console.log("网站密钥: " + websiteKey);
console.log("上下文: " + context);
console.log("IV: " + iv);
console.log("挑战脚本 URL: " + challengeScriptUrl);
console.log("验证码脚本 URL: " + captchaScriptUrl);
创建请求、提交任务到服务器、获取结果
一旦拥有所有 CAPTCHA 参数,就可以创建一个任务提交给 CapMonster Cloud 服务器。
示例请求:
使用方法: https://api.capmonster.cloud/createTask 请求格式: JSON POST
{
"clientKey": "API_KEY",
"task": {
"type": "AmazonTaskProxyless",
"websiteURL": "https://efw47fpad9.execute-api.us-east-1.amazonaws.com/latest",
"challengeScript": "https://41bcdd4fb3cb.610cd090.us-east-1.token.awswaf.com/41bcdd4fb3cb/0d21de737ccb/cd77baa6c832/challenge.js",
"captchaScript": "https://41bcdd4fb3cb.610cd090.us-east-1.captcha.awswaf.com/41bcdd4fb3cb/0d21de737ccb/cd77baa6c832/captcha.js",
"websiteKey": "AQIDA...wZwdADFLWk7XOA==",
"context": "qoJYgnKsc...aormh/dYYK+Y=",
"iv": "CgAAXFFFFSAAABVk",
"cookieSolution": true
}
}
示例响应:
{
"errorId": 0,
"taskId": 407533072
}
检索结果:
使用 getTaskResult 方法获取 AmazonTask 的解决方案。
https://api.capmonster.cloud/getTaskResult
示例响应:
{
"errorId": 0,
"status": "ready",
"solution": {
"cookies": {
"aws-waf-token": "10115f5b-ebd8-45c7-851e-cfd4f6a82e3e:EAoAua1QezAhAAAA:dp7sp2rXIRcnJcmpWOC1vIu+yq/A3EbR6b6K7c67P49usNF1f1bt/Af5pNcZ7TKZlW+jIZ7QfNs8zjjqiu8C9XQq50Pmv2DxUlyFtfPZkGwk0d27Ocznk18/IOOa49Rydx+/XkGA7xoGLNaUelzNX34PlyXjoOtL0rzYBxMAQy0D1tn+Q5u97kJBjs5Mytqu9tXPIPCTSn4dfXv5llSkv9pxBEnnhwz6HEdmdJMdfur+YRW1MgCX7i3L2Y0/CNL8kd8CEhTMzwyoXekrzBM="
},
"userAgent": "userAgentPlaceholder"
}
}
在 Python 中解决亚马逊 CAPTCHA 的示例代码:
在网络抓取过程中,可能会遇到各种障碍,例如亚马逊 CAPTCHA 出现在目标网站上导致脚本中断。要绕过这一障碍,可以在抓取器中添加额外的代码以自动解决 CAPTCHA。此代码将等待 CAPTCHA 框架,提取所有必要参数,并将解决方案发送到 CapMonster Cloud 服务器。
以下是实现方法:假设有一个使用 Selenium 的 Python 抓取天气网站的脚本:
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import os
import requests
import time
# CapMonster Cloud 的 API_KEY
API_KEY = os.getenv('CAPMONSTER_API_KEY')
CREATE_TASK_URL = 'https://api.capmonster.cloud/createTask'
GET_TASK_RESULT_URL = 'https://api.capmonster.cloud/getTaskResult'
def create_task(website_key, context, iv, challenge_script_url, captcha_script_url):
print("创建任务中...")
task_data = {
"clientKey": API_KEY,
"task": {
"type": "AmazonTaskProxyless",
"websiteURL": 'https://example.com', # 替换为正确的值
"challengeScript": challenge_script_url,
"captchaScript": captcha_script_url,
"websiteKey": website_key,
"context": context,
"iv": iv,
"cookieSolution": False # 如果需要“aws-waf-token” cookies,设置为 True
}
}
response = requests.post(CREATE_TASK_URL, json=task_data)
response_json = response.json()
if response_json['errorId'] == 0:
print(f"任务创建成功。任务 ID: {response_json['taskId']}")
return response_json['taskId']
else:
print(f"创建任务时出错: {response_json['errorCode']}")
return None
def get_task_result(task_id):
print("获取任务结果中...")
result_data = {"clientKey": API_KEY, "taskId": task_id}
while True:
response = requests.post(GET_TASK_RESULT_URL, json=result_data)
response_json = response.json()
if response_json['status'] == 'ready':
print(f"任务结果已准备好: {response_json}")
return response_json
elif response_json['status'] == 'processing':
print("任务仍在处理中...")
time.sleep(5)
else:
print(f"检索任务结果时出错: {response_json['errorCode']}")
return response_json
# 启动浏览器
driver = webdriver.Chrome()
try:
# 打开主页
print("打开页面中...")
driver.get('https://example.com')
# 输入搜索城市
search_box = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.ID, "header-location-search"))
)
search_box.send_keys("Moscow") # 替换为所需的城市
search_box.send_keys(Keys.RETURN)
# 等待 CAPTCHA iframe 出现
print("等待 iframe...")
iframe = WebDriverWait(driver, 20).until(
EC.presence_of_element_located((By.CSS_SELECTOR, 'iframe[src*="execute-api"]'))
)
driver.switch_to.frame(iframe)
print("等待 CAPTCHA,提取参数中...")
WebDriverWait(driver, 20).until(
EC.presence_of_element_located((By.CSS_SELECTOR, '#captcha-container'))
)
goku_props = driver.execute_script("return window.gokuProps;")
website_key = goku_props["key"]
context = goku_props["context"]
iv = goku_props["iv"]
challenge_script_url, captcha_script_url = [
driver.execute_script(f"return document.querySelector('script[src*=\"{x}\"]').src;")
for x in ("challenge.js", "captcha.js")
]
# 创建并解决 CAPTCHA 任务
task_id = create_task(website_key, context, iv, challenge_script_url, captcha_script_url)
if task_id:
result = get_task_result(task_id)
# 根据需要使用结果提交 CAPTCHA 解决方案
# 解决 CAPTCHA 后继续处理搜索结果
WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.CSS_SELECTOR, 'div.locations-list')) # 替换为正确的值
)
first_result = driver.find_element(By.CSS_SELECTOR, 'div.locations-list a') # 替换为正确的值
first_result.click()
# 其他操作...
finally:
print("关闭浏览器中...")
driver.quit()
更新代码的详细说明:
- 额外的库导入:
requests
用于发送 HTTP 请求与 CapMonster Cloud API 交互,time
用于暂停代码执行。
- API 密钥和 URL 变量:
- 变量用于存储用于身份验证的 API 密钥以及用于创建任务和检索结果的 URL。
- 任务创建函数:
- 一个函数,用于创建 CAPTCHA 解决任务。它将 POST 请求发送到 CapMonster Cloud 服务器,如果任务创建成功,函数返回
taskId
。
- 一个函数,用于创建 CAPTCHA 解决任务。它将 POST 请求发送到 CapMonster Cloud 服务器,如果任务创建成功,函数返回
- 任务结果函数:
- 一个函数,用于发送 POST 请求以检查任务状态。如果任务状态为“ready”,函数返回结果;否则,它等待并再次检查状态。
- 浏览器初始化和目标页面打开:
- 等待搜索字段出现,输入城市名称,并等待 CAPTCHA iframe 出现。
- CAPTCHA 参数提取:
- 更新后的代码从 iframe 的脚本中提取
website_key
、context
和iv
值,并用它们在 CapMonster Cloud 服务器上创建任务。
- 更新后的代码从 iframe 的脚本中提取
- CAPTCHA 解决工作流程:
- 代码现在包括创建任务和周期性检查 CAPTCHA 是否已解决。解决 CAPTCHA 后,执行其他操作。
提示和建议:
- 上述代码是演示执行操作的一般逻辑的示例。所有操作和元素名称取决于特定网站及其结构。您需要研究网站的 HTML 代码,并熟悉您计划用于网络抓取的工具文档。每个网站都是独特的,成功抓取可能需要根据目标资源的特性调整代码和方法。此外,处理亚马逊 CAPTCHA 具有其细微差别,需要注意。
以下是成功进行网络抓取和解决亚马逊 CAPTCHA (AWS WAF) 的一些通用提示:
- 异步编程:在我们的简单抓取和 CAPTCHA 解决示例中,没有使用异步方法。然而,如果您处理大量数据或响应时间较慢的网站,最好使用异步编程进行并行任务执行,以加快处理速度。
- 无头模式:以无头模式运行浏览器,以加快工作速度和节省资源。在不显示浏览器图形界面的情况下,过程可以更高效。
- 图形浏览器:如果网站需要复杂的交互,而这些交互在无头模式下不可能实现,请使用图形浏览器。这将帮助您处理界面元素,更好地测试代码,并避免一些错误和网站限制,当检测到无头浏览器时可能会限制访问。
- 更改 IP 地址和用户代理:为了避免网站的阻止和限制,请定期更改 IP 地址和用户代理。使用优质代理服务器,并在请求中更改用户代理,以便网站不会怀疑自动化行为。
- 处理动态 CAPTCHA:亚马逊使用的 CAPTCHA 可能会根据时间或活动变化,并不断更新其反机器人保护方法。确保您的脚本能够适应这些变化并正确处理。跟踪 CAPTCHA 解决服务的更新和新闻。
- 减少请求频率:避免过于频繁地发送请求,以免引起亚马逊反机器人系统的注意,或在不同的 IP 地址之间分发请求。
有用的链接:
解决亚马逊 CAPTCHA (AWS WAF) 在数据收集时可能会面临重大挑战。然而,理解该系统的基本原理并使用正确的工具可以有效管理这些任务。
我们已经涵盖了关键点,包括这种类型的 CAPTCHA 及其通过 CapMonster Cloud 解决的描述。最关键的阶段是准确提取所需的 CAPTCHA 参数,创建并发送任务到服务器,并获取和使用 CAPTCHA 解决方案。我们还回顾了一个 Python 代码示例,演示了如何将 CAPTCHA 解决方案集成到网络抓取过程中。该领域的成功不仅依赖于技术技能,还取决于快速适应反机器人保护方法的变化和创新能力。
注意:我们提醒您,产品用于自动化测试您自己的网站以及您合法访问的网站。