从 Flask 后端调用 solvethree

作者:solvethree阅读需 1 分钟

使用独立的 Flask 接口创建和查询 solvethree 任务。下方的 POST 会在不等待整个求解过程结束的情况下返回;调用方保留任务 ID,并持续检查 GET 接口,直到任务就绪或失败。

本页内容

安装依赖并配置目标

  1. 1.

    使用 Python 3.10 或更高版本

    运行 python -m pip install flask 安装 Flask。运行 python -m pip install https://solvethree.com/downloads/solvethree_sdk-0.1.0-py3-none-any.whl 安装官方 Python SDK。

  2. 2.

    设置服务器环境变量

    将 SOLVETHREE_API_KEY 设置为工作区 API 密钥,将 INTEGRATION_KEY 设置为已获授权的调用方将在 X-Integration-Key 中发送的密钥。将 CAPTCHA_SITE 设置为目标主机名,而不是完整 URL,并将 SOLVETHREE_PROXY 设置为此任务使用的 HTTP 或 HTTPS 代理 URL。请将这些值保留在服务器上。

  3. 3.

    启用站点配置文件

    在 solvethree 控制台中为该主机名配置一个已启用且工作区可用的配置。设置 CAPTCHA_SITE 不会创建配置。如果尚未配置目标,请参阅站点配置设置。

示例将操作固定为 login,并使用默认的 reCAPTCHA Enterprise v3 任务。运行前,请更改该操作以匹配目标操作。调用方无法通过请求正文覆盖站点、操作或代理。

添加创建和查询接口

Flask · 创建并获取同一任务
# pip install flask and the official solvethree SDK wheel.
import hmac
import os
from flask import Flask, abort, jsonify, request
from solvethree import Solvethree, SolvethreeError

app = Flask(__name__)

def client():
    return Solvethree(os.environ["SOLVETHREE_API_KEY"])

@app.before_request
def authorize():
    if not hmac.compare_digest(request.headers.get("x-integration-key", ""), os.environ["INTEGRATION_KEY"]):
        abort(401)

@app.errorhandler(SolvethreeError)
def task_error(error):
    return jsonify(requestId=error.request_id, taskId=error.task_id), 502

@app.errorhandler(ValueError)
def invalid_input(error):
    return jsonify(error="Invalid task input or ID"), 400

@app.post("/captcha/tasks")
def create():
    task = {"site": os.environ["CAPTCHA_SITE"], "action": "login", "proxy": os.environ["SOLVETHREE_PROXY"]}
    if request.headers.get("x-request-id"):
        task["requestId"] = request.headers["x-request-id"]
    return jsonify(client().create_task(task, wait_ms=0, timeout=20))

@app.get("/captcha/tasks/<task_id>")
def retrieve(task_id):
    return jsonify(client().get_task(task_id, wait_ms=15000, timeout=25))

将示例保存为 app.py。设置环境变量后,运行 python -m flask --app app run 在本地启动。接口为 POST /captcha/tasks 和 GET /captcha/tasks/<task_id>。Flask 不需要单独的 URLconf:装饰器会注册这两个接口。有关本地启动的详细信息,请参阅 Flask 快速入门;保留现有的生产环境 WSGI 配置。

创建时使用 wait_ms=0,网络超时为 20 秒。这会跳过等待求解,但不会跳过 HTTP 请求本身。查询时允许最多等待 15 秒以获取任务更新,网络超时为 25 秒。两个视图都使用同步 SDK,因此在 SDK 调用运行期间,各自都会占用处理该请求的工作进程。

发送 POST 前保存请求 ID

  1. 1.

    为每个逻辑任务创建一个请求 ID

    在调用 POST /captcha/tasks 前保存它,然后将其作为 X-Request-ID 与 X-Integration-Key 一起发送。使用 1–64 个 ASCII 字母、数字、下划线或连字符。此 POST 无需任务请求体,因为服务器会根据固定配置构建任务。

  2. 2.

    保留返回的任务 ID

    收到成功的 HTTP 响应后,保存结果中的 id。通过 GET /captcha/tasks/<task_id> 获取任务,并再次发送 X-Integration-Key。

  3. 3.

    创建结果不确定时恢复原任务,而非另建任务

    如果 POST 连接超时,任务仍可能已成功创建。如果已有任务 ID,就获取该任务。否则,使用相同的 X-Request-ID 和未更改的任务输入重新发送 POST,以恢复已有任务。更改站点、操作或代理后复用该 ID 会产生冲突。

示例中此请求头为可选项,但如果创建成功而响应丢失,省略它就无法通过此方式恢复。不要仅因为首次请求超时就生成新 ID。

先处理 HTTP 错误,再检查任务状态

首先检查 Flask 响应的 HTTP 状态。示例在集成密钥缺失或不正确时返回 401,捕获到 ValueError 时返回 400,捕获到 SolvethreeError 时返回 502。该 502 响应体会提供 requestId 和 taskId 以便恢复;它不是任务状态载荷,本身也不表示任务失败。

收到成功的 HTTP 响应后,检查任务状态。
收到成功的 HTTP 响应后,检查任务状态。
任务状态调用方操作
待处理保留同一个任务 ID,再次获取任务。
求解中保留同一个任务 ID,再次获取任务。
ready停止轮询并读取解决方案。
failed停止轮询并检查 errorCode 和 error。求解失败会退款。

使用原始代理和返回的身份提交令牌

只有 ready 结果才包含可用的解决方案。将 solution.token 而非任务 ID 发送给预期目标,并使用返回的 solution.userAgent 和 solution.secChUa 浏览器身份信息。

通过创建任务时使用的同一代理提交。此示例使用固定的 SOLVETHREE_PROXY,因此应随任务保存原始代理配置,而不要假定当前环境变量的值之后仍会与之匹配。Flask 路由返回 SDK 结果;它们不会向目标提交,也不会配置调用方的代理。

将令牌、代理、浏览器身份信息和预期目标一并保存。任务就绪表示 solvethree 已生成解决方案;是否被接受,取决于目标对后续应用请求的响应。

运行您的第一个任务。

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

创建工作区
从 Flask 后端调用 solvethree · solvethree