提交求解后的令牌时保留应用 Cookie

作者:solvethree阅读需 1 分钟

求解得到的 reCAPTCHA 令牌不能替代应用的会话 Cookie 或 CSRF 值。通过同一个 requests.Session 获取并提交表单,使 POST 保留 GET 期间收到的 Cookie。

两次应用请求都应使用求解器返回的浏览器请求头和同一个代理。此示例先进行求解,以便在打开表单前获得这些请求头。

本页内容

在同一会话中执行表单 GET 和 POST

使用 Python 3.10+,并安装 requests 和官方 solvethree Python SDK。目标主机名需要在工作区中有一个启用的配置;在任务中发送主机名不会创建配置。如果尚未配置,请参阅站点配置设置。

  • 将 TARGET_URL 设为应用的表单 URL。此自有演示使用同一个 URL 执行 GET 和 POST。
  • 将 SOLVETHREE_PROXY 设为求解和两次应用请求共用的单个代理。
  • 将 SOLVETHREE_API_KEY 设为工作区 API 密钥。在服务端运行此代码。
requests.Session · 保留应用 Cookie 和 CSRF 值
# This owned demo form has an input named csrf_token and g-recaptcha-response.
import os
from html.parser import HTMLParser
from urllib.parse import urlsplit
import requests
from solvethree import Solvethree

class FormParser(HTMLParser):
    csrf = None
    def handle_starttag(self, tag, attributes):
        values = dict(attributes)
        if tag == "input" and values.get("name") == "csrf_token":
            self.csrf = values.get("value")

target = os.environ["TARGET_URL"]
proxy = os.environ["SOLVETHREE_PROXY"]
request = {"site": urlsplit(target).hostname, "action": "login", "proxy": proxy}
# Obtain the solver's browser headers before opening the application session.
result = Solvethree(os.environ["SOLVETHREE_API_KEY"]).solve(request, timeout=180)
solution = result["solution"]
with requests.Session() as session:
    session.headers.update({"User-Agent": solution["userAgent"], "sec-ch-ua": solution["secChUa"]})
    proxies = {"http": proxy, "https": proxy}
    page = session.get(target, proxies=proxies, timeout=20, allow_redirects=False)
    page.raise_for_status()
    parser = FormParser(); parser.feed(page.text)
    if not parser.csrf: raise RuntimeError("The expected demo CSRF input was not found")
    response = session.post(target, proxies=proxies, timeout=20, allow_redirects=False,
        data={"csrf_token": parser.csrf, "g-recaptcha-response": solution["token"]})
    print("Application HTTP status:", response.status_code)
    # Use the actual form's submit URL, fields and session rules. Inspect its result.

SDK 的 solve 调用会创建任务并轮询,直到任务就绪或抛出异常。随后,示例将 solution.userAgent 和 solution.secChUa 应用到会话。GET 会填充会话的 Cookie 容器;POST 会复用该容器,并将 solution.token 与从表单解析出的 CSRF 值一起提交。

修改演示中的 login 操作、提交 URL 和表单字段,使其与你的应用一致。csrf_token 是此表单的字段名,并非 solvethree 的要求。如果你的表单使用其他名称或结构,请调整 HTML 解析器,并包含其他所有必填字段,例如登录凭据。如果提交 URL 与表单 URL 不同,仍应使用同一个会话。

如果应用拒绝 POST

打印出的 HTTP 状态只是排查起点,不能证明登录成功。在付费进行另一次求解前,请检查应用响应和发出的请求。任务就绪表示已生成解答;应用仍会自行决定是否接受提交。

未找到 CSRF 输入字段。

检查 GET 响应的状态和正文。自动跟随重定向已禁用,因此重定向响应并非预期的表单。

试试这样做: 通过同一个会话明确获取正确的表单,然后根据其实际 CSRF 字段调整解析器。

应用报告会话缺失或 CSRF 值无效。

检查 GET 是否收到了 Cookie、POST 是否发送了适用的 Cookie,以及其 CSRF 值是否来自该表单响应。

试试这样做: 两次请求都应使用同一个 requests.Session。不要使用一个客户端获取表单,再用另一个客户端提交。

应用拒绝了 CAPTCHA。

检查发出的令牌字段、action、代理、User-Agent 和 sec-ch-ua。确认发送的是 solution.token,而不是任务 ID 或旧令牌。

试试这样做: 使用当前令牌、求解时使用的同一个代理,以及返回的浏览器请求头。如果令牌已过期或已被评估,请在接近提交时获取新令牌。

POST 已完成,但登录未成功。

检查响应正文和所有重定向目标,以及实际提交 URL 和必填表单字段。

试试这样做: 根据应用约定调整演示的表单数据。CAPTCHA 令牌不会提供凭据或其他缺失的应用字段。

运行您的第一个任务。

使用 $5 工作区额度开始体验。

创建工作区
提交求解后的令牌时保留应用 Cookie · solvethree