CAPSOLVER
博客
如何使用PHP解决AWS验证码/挑战

如何使用 PHP 解决 AWS 验证码/挑战:全面指南

Logo of CapSolver

Emma Foster

Machine Learning Engineer

10-Dec-2025

TLDR

本指南提供了一个全面的分步教程,介绍如何使用PHP和CapSolver API绕过AWS WAF CAPTCHA和Challenge页面。我们详细说明了检测CAPTCHA(HTTP 405)和Challenge(HTTP 202)响应的逻辑,提取必要的参数,并使用生成的aws-waf-token cookie访问受保护的资源。

引言

欢迎阅读本全面指南,我们将深入探讨AWS CAPTCHA以及如何实现PHP解决方案。对于开发人员和网络爬虫来说,遇到CAPTCHA可能是一个重大障碍,但借助合适的工具,这将成为一项可管理的任务。

什么是AWS WAF CAPTCHA和Challenge?

AWS WAF(Web应用防火墙)是一种安全服务,可帮助保护网络应用程序免受常见网络攻击。它提供了两种主要操作,以验证请求是否来自合法的人类用户而非机器人:CAPTCHAChallenge

AWS WAF操作概述

操作 目的 HTTP状态码 所需解决方案
Challenge 运行无声的后台验证,以确认客户端会话是标准浏览器。 202 Accepted 需要解决JavaScript挑战以获取令牌。
CAPTCHA 要求最终用户解决视觉谜题以证明他们是人类。 405 Method Not Allowed 需要解决视觉CAPTCHA,这需要从页面中提取特定参数。

一旦成功解决CAPTCHA或Challenge,AWS WAF会颁发一个有效的令牌,作为名为aws-waf-token的cookie返回。此令牌必须包含在后续请求中以绕过WAF保护。

🔎 使用PHP和CapSolver解决AWS CAPTCHA/Challenge

CapSolver提供了一个强大的API解决方案,用于处理AWS WAF提供的无声Challenge和视觉CAPTCHA。本指南重点介绍使用PHP的cURL库实现必要的逻辑。

📕 要求

  • PHP(启用cURL扩展)
  • cURL
  • CapSolver API密钥(您可以通过CapSolver注册获取)

🛠️ 第1步:设置环境和辅助函数

我们的解决方案核心涉及向CapSolver发送两个主要API调用:createTask用于提交CAPTCHA/Challenge,getTaskResult用于获取解决方案。

PHP 复制代码
<?php

// --- 配置 ---
$PROXY = "http://username:password@host:port"; // 可选:替换为您的代理信息(例如用于AntiAwsWafTask)
$PAGE_URL = "https://norway-meetup.aws.wslab.no/";  // 替换为受AWS WAF保护的目标URL
$CLIENT_KEY = "YourPayPerUsage";  // 替换为您的CAPSOLVER API密钥

/**
 * 向CapSolver API提交任务。
 * @param array $payload 包含类型和参数的任务负载。
 * @return array API响应,包括taskId。
 */
function createTask($payload) {
    global $CLIENT_KEY;
    $ch = curl_init();
    echo("创建任务...\n");
    curl_setopt($ch, CURLOPT_URL, 'https://api.capsolver.com/createTask');
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode(['clientKey' => $CLIENT_KEY, 'task' => $payload]));
    curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
    $response = curl_exec($ch);
    curl_close($ch);
    return json_decode($response, true);
}

/**
 * 轮询CapSolver API以获取任务结果。
 * @param string $taskId 要检查的任务ID。
 * @return array API响应,包含解决方案。
 */
function getTaskResult($taskId) {
    global $CLIENT_KEY;
    do {
        echo("等待解决方案...\n");
        sleep(1);
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, 'https://api.capsolver.com/getTaskResult');
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode(['clientKey' => $CLIENT_KEY, 'taskId' => $taskId]));
        curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
        $response = curl_exec($ch);
        curl_close($ch);
        $data = json_decode($response, true);
        
        if (isset($data['status']) && $data['status'] == "ready") {
            return $data;
        }
        
        // 处理getTaskResult可能的错误
        if (isset($data['errorId']) && $data['errorId'] != 0) {
            echo("获取任务结果时出错: " . $data['errorDescription'] . "\n");
            return null;
        }
        
    } while(true);
}

/**
 * 使用适当的task类型解决AWS WAF Challenge或Captcha。
 * @param string $taskType CapSolver的task类型(AntiAwsWafTask或AwsCaptchaTask)。
 * @param array $params 任务所需的参数。
 * @return string|null aws-waf-token cookie值或失败时为null。
 */
function solveAwsWaf($taskType, $params) {
    global $PAGE_URL, $PROXY;
    
    $payload = [
        'type' => $taskType,
        'websiteURL' => $PAGE_URL,
        'proxy' => $PROXY,
    ];
    
    // 合并特定任务参数
    $payload = array_merge($payload, $params);
    
    // 清理空值以获得更简洁的请求
    $payload = array_filter($payload, function($value) {
        return $value !== "" && $value !== null;
    });

    $taskData = createTask($payload);
    
    if (isset($taskData['taskId'])) {
        $result = getTaskResult($taskData['taskId']);
        if ($result && isset($result['solution']['cookie'])) {
            return $result['solution']['cookie'];
        }
    }
    
    return null;
}

⚡ 第2步:实现WAF检测和解决逻辑

主要逻辑包括向受保护页面发送初始请求并检查HTTP状态码以确定是否需要Challenge(202)或CAPTCHA(405)。然后使用正则表达式从HTML响应体中提取必要的参数。

PHP 复制代码
// --- 主执行逻辑 ---

// 1. 向受保护页面发送初始请求
$ch = curl_init($PAGE_URL);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

$cookie = null;

echo("初始HTTP代码: " . $httpCode . "\n");

if ($httpCode == 202) {
    // --- Challenge(202)处理 ---
    echo("检测到Challenge(HTTP 202)。提取参数...\n");
    
    // 提取challenge.js的URL
    preg_match('/<script src="([^"]*token.awswaf.com[^"]*)"/', $response, $matches);
    $awsChallengeJS = $matches[1] ?? null;
    
    if ($awsChallengeJS) {
        $params = ['awsChallengeJS' => $awsChallengeJS];
        $cookie = solveAwsWaf("AntiAwsWafTask", $params);
    } else {
        echo("错误:未找到Challenge的awsChallengeJS。\n");
    }

} elseif ($httpCode == 405) {
    // --- CAPTCHA(405)处理 ---
    echo("检测到CAPTCHA(HTTP 405)。提取参数...\n");
    
    // 从页面内容中提取参数
    preg_match('/<script src="([^"]*token.awswaf.com[^"]*)"/', $response, $matches);
    $awsChallengeJS = $matches[1] ?? null;
    
    preg_match('/"key":"(.*?)"/', $response, $matches);
    $awsKey = $matches[1] ?? null;
    
    preg_match('/"iv":"(.*?)"/', $response, $matches);
    $awsIv = $matches[1] ?? null;
    
    preg_match('/"context":"(.*?)"/', $response, $matches);
    $awsContext = $matches[1] ?? null;
    
    if ($awsKey && $awsIv && $awsContext) {
        $params = [
            'awsKey' => $awsKey,
            'awsIv' => $awsIv,
            'awsContext' => $awsContext,
            'awsChallengeJS' => $awsChallengeJS // 可选但推荐
        ];
        // 注意:视觉CAPTCHA的任务类型通常是AntiAwsWafTask, 
        // 但传递的参数决定了CapSolver端的解决方案类型。
        $cookie = solveAwsWaf("AntiAwsWafTask", $params); 
    } else {
        echo("错误:未找到CAPTCHA的key、IV或context参数。\n");
    }
}

// 3. 使用令牌访问受保护资源
if ($cookie) {
    echo("成功获取aws-waf-token。发送最终请求...\n");
    
    $ch = curl_init($PAGE_URL);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    // 设置aws-waf-token cookie
    curl_setopt($ch, CURLOPT_COOKIE, "aws-waf-token=" . $cookie);
    
    $finalResponse = curl_exec($ch);
    curl_close($ch);
    
    echo "\n--- 最终页面内容 ---\n";
    echo $finalResponse;
    echo "\n--------------------------\n";
} else {
    echo("未能解决AWS WAF Challenge/CAPTCHA。\n");
}

?>

代码优化说明

原始代码使用了单独的函数(solveAwsChallenge、solveAwsCaptcha)和略有不一致的参数命名(key、iv、context与awsKey、awsIv、awsContext)。优化后的代码将其整合为一个solveAwsWaf函数,与CapSolver最新API文档保持一致,确保更易于维护和模块化。

此逻辑在网页爬虫和自动化任务中非常有效。对于其他语言的开发者,CapSolver也提供了类似“如何使用Python解决AWS CAPTCHA/Challenge”的指南[https://www.capsolver.com/blog/how-to-solve-aws-captcha-challenge-with-python],遵循类似的API模式。

结论

AWS WAF的Challenge和CAPTCHA机制是有效的反机器人措施,但并非不可逾越。通过在PHP中实现强大的检测和解决逻辑,利用CapSolver API的力量,开发人员可以可靠地获得必要的aws-waf-token cookie,从而继续他们的网页爬虫或自动化任务。关键在于通过HTTP状态码正确识别WAF操作,并从页面源代码中准确提取所需参数。

关键要点

  • AWS WAF操作: AWS WAF使用无声的Challenge(HTTP 202)或视觉的CAPTCHA(HTTP 405)来阻止机器人。
  • 目标: 最终目标是获取aws-waf-token cookie值。
  • CapSolver API: AntiAwsWafTask任务类型可以处理Challenge和CAPTCHA的解决,所需参数决定了CapSolver的具体解决方案。
  • PHP实现: 使用PHP的cURL进行请求,preg_match对于从HTML源代码中提取动态参数(如awsChallengeJSawsKeyawsIvawsContext至关重要。
  • 可靠性: 对于稳定、高吞吐量的自动化,集成专门的求解器如CapSolver至关重要,如AWS WAF CAPTCHA求解器:网络爬虫的令牌和图像解决方案中所详细说明的。

FAQ:常见问题

Q1:为什么我需要检查HTTP状态码(202或405)?

A: HTTP状态码是判断所需WAF操作类型的最可靠指标。202 Accepted状态码表示正在运行无声Challenge,需要较少的参数。405 Method Not Allowed状态码表示正在运行视觉CAPTCHA,需要从页面的JavaScript变量中提取更具体的参数(key、iv、context)。

Q2:AntiAwsWafTaskAntiAwsWafTaskProxyLess有什么区别?

A: 两种任务类型都设计用于解决AWS WAF Challenge。主要区别在于是否需要代理。AntiAwsWafTask要求您在请求负载中提供自己的代理。AntiAwsWafTaskProxyLess不需要代理,因为CapSolver内部处理代理使用。对于大规模网络爬虫,使用代理通常推荐以保持匿名并避免IP封禁。

Q3:我的脚本无法找到key、iv或context参数。我该怎么办?

A: 这些参数是动态生成并嵌入在HTML源代码中的,通常在<script>标签或隐藏输入字段中。如果preg_match失败,可能是由于目标网站的WAF实现发生了变化。您应检查被阻止页面的最新HTML源代码以更新正则表达式。

Q4:我能否不使用第三方服务解决AWS WAF?

A: 手动解决AWS WAF挑战非常困难且不适用于自动化。Challenge操作需要执行复杂的混淆JavaScript,CAPTCHA操作需要解决图像识别难题。第三方服务如CapSolver使用先进的人工智能和大规模基础设施实时解决这些挑战,使自动化成为可能。为每种CAPTCHA构建内部求解器通常不具成本效益或可靠性。

Q5:aws-waf-token的有效期是多久?

A: aws-waf-token的有效期由受保护网站的AWS WAF配置决定,但通常为10-30分钟。一旦令牌过期,您需要重复解决过程(初始请求、检测和任务提交)以获取新令牌。

合规声明: 本博客提供的信息仅供参考。CapSolver 致力于遵守所有适用的法律和法规。严禁以非法、欺诈或滥用活动使用 CapSolver 网络,任何此类行为将受到调查。我们的验证码解决方案在确保 100% 合规的同时,帮助解决公共数据爬取过程中的验证码难题。我们鼓励负责任地使用我们的服务。如需更多信息,请访问我们的服务条款和隐私政策。

更多