在 Django 视图中使用 solvethree

作者:solvethree阅读需 1 分钟

在 POST 视图中创建任务,返回任务 ID,然后让调用方获取其状态。不要让创建请求一直保持连接,直到求解完成。

提供的视图使用已配置的 reCAPTCHA Enterprise 目标和单个代理。它们应放在已启用身份验证和标准 CSRF 中间件的现有 Django 项目中。

本页内容

安装 SDK 并配置目标

  1. 1.

    在 Django 环境中安装

    官方 SDK 要求 Python 3.10+。在运行 Django 的环境中,执行 python -m pip install https://solvethree.com/downloads/solvethree_sdk-0.1.0-py3-none-any.whl。

  2. 2.

    设置服务器环境变量

    将 SOLVETHREE_API_KEY 设为工作区 API 密钥,将 CAPTCHA_SITE 设为目标主机名而非完整 URL,并将 SOLVETHREE_PROXY 设为用于求解和后续向目标提交的代理。请将 API 密钥和代理凭据保留在服务器端。

  3. 3.

    激活站点配置

    在控制台中为该主机名配置一个已激活且可供你的工作区使用的配置。发送主机名和操作不会创建配置。请参阅站点配置设置。

示例将操作固定为 login,且不接受调用方提供的目标设置。如果配置的目标需要其他操作,请修改该操作。请求使用默认的 enterprise-v3 模式;它需要 site、action,以及 proxy 或 proxyCandidates 中恰好一个参数,而不是 type 或 url。

添加需要身份验证的视图

Django · 使用常规 CSRF 防护的身份验证视图
# views.py in an existing Django project with authentication/CSRF configured.
import os
from django.contrib.auth.decorators import login_required
from django.http import JsonResponse
from django.views.decorators.http import require_GET, require_POST
from solvethree import Solvethree, SolvethreeError

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

@login_required
@require_POST
def create_captcha(request):
    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"]
    try:
        return JsonResponse(client().create_task(task, wait_ms=0, timeout=20))
    except ValueError:
        return JsonResponse({"error": "Invalid task input"}, status=400)
    except SolvethreeError as error:
        return JsonResponse({"requestId": error.request_id, "taskId": error.task_id}, status=502)

@login_required
@require_GET
def get_captcha(request, task_id):
    try:
        return JsonResponse(client().get_task(task_id, wait_ms=15000, timeout=25))
    except ValueError:
        return JsonResponse({"error": "Invalid task ID"}, status=400)
    except SolvethreeError as error:
        return JsonResponse({"requestId": error.request_id, "taskId": error.task_id}, status=502)

# urls.py: import these views and add to urlpatterns:
# path("captcha/tasks", create_captcha),
# path("captcha/tasks/<str:task_id>", get_captcha),

create_task 使用 wait_ms=0,因此会直接返回任务,而不等待整个求解过程完成。其 HTTP 调用的超时时间为 20 秒。获取视图最多可等待 15 秒以获取任务更新,HTTP 超时时间为 25 秒。这些都是同步 SDK 调用:获取请求在等待期间仍会占用 Django 工作进程。

login_required 将访问权限限制为已登录用户;方法装饰器允许通过 POST 创建任务、通过 GET 获取任务。保留 Django 的常规 CSRF 保护,并在发送 POST 时附带其 CSRF 令牌。不要添加 csrf_exempt。

接入路由并启动 Django

  1. 1.

    更新现有 URLconf

    从 django.urls 导入 path,并从应用的视图模块导入 create_captcha 和 get_captcha。将示例底部的两个路由条目添加到现有的 urlpatterns 中。如果使用应用级 URLconf,请确保项目 URLconf 已包含它。

  2. 2.

    启动开发服务器

    确保进程可以读取这些环境变量,然后在包含 manage.py 的目录中运行 python manage.py runserver。调用端点前,请先通过项目现有的登录流程登录。

  3. 3.

    使用已注册的路径

    如果没有外层 URL 前缀,创建任务使用 POST /captcha/tasks,获取任务使用 GET /captcha/tasks/<task_id>。提供的路由没有末尾斜杠。请包含项目 URLconf 引入的所有前缀。

创建一次,然后获取任务

  1. 1.

    发送 POST 前保存 ID

    为每个逻辑任务选择一个新的 X-Request-ID,并保留它,直到创建结果确定。使用 1–64 个 ASCII 字母、数字、下划线或连字符。视图会将此请求头作为任务的 requestId 转发。

  2. 2.

    先确认 HTTP 请求成功,再检查任务状态

    示例在捕获到输入验证错误时返回 HTTP 400,捕获到 SDK 错误时返回 502。成功响应包含任务载荷;请读取其中的 id 和 status。HTTP 成功表示请求成功,而不表示令牌已就绪。

  3. 3.

    持续获取,直到任务结束

    使用返回的任务 ID 调用 GET 端点。状态为 pending 或 solving 时继续获取。状态为 ready 时使用解决方案。状态为 failed 时停止轮询,并检查 errorCode 和 error;求解失败会退款。请修正无效输入,而不是原样重试。

  4. 4.

    恢复创建结果不确定的任务

    如果 POST 超时或返回 SDK 错误,不要立即使用新 ID 创建另一个任务。如果已知任务 ID,请获取现有任务。否则,使用原始 X-Request-ID 和未更改的任务输入重新发送 POST,以恢复该任务。将该 ID 用于不同输入会产生冲突,包括更改已配置的主机名、操作或代理。

SDK 错误响应包含异常中的 requestId 和 taskId,以便诊断。请单独保存调用方原始的 X-Request-ID,以免恢复依赖于能否收到该响应。有关失败处理,请参阅 CAPTCHA API 错误。

使用相同代理和返回的身份信息提交令牌

只有 ready 任务才包含可用的解决方案。发送给预期目标的值应为 solution.token,而非任务 ID。请使用返回的 solution.userAgent 和 solution.secChUa 浏览器身份信息,以及最初在 SOLVETHREE_PROXY 中配置的代理。

这些视图不会向目标提交任何内容。你的提交代码必须保留该代理并应用返回的身份信息;将令牌返回给无关的浏览器会话并不会自动做到这一点。请将代理凭据保留在服务器端,不要将解决方案与其他目标 URL 或浏览器身份信息混用。

运行您的第一个任务。

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

创建工作区
在 Django 视图中使用 solvethree · solvethree