Вызывайте API CAPTCHA из PowerShell

Автор: solvethree4 мин на чтение

Используйте PowerShell 7.5+ и Invoke-RestMethod для прямого вызова solvethree. Скрипт ниже создаёт одну задачу reCAPTCHA Enterprise и опрашивает тот же идентификатор задачи до её завершения или исчерпания локального лимита ожидания.

На этой странице

Задайте учётные данные и параметры целевого сайта

  1. 1.

    Сделайте сайт доступным в рабочем пространстве

    Настройте активный профиль для целевого имени хоста в консоли. Отправка имени хоста и действия не создаёт профиль. См. настройку профиля сайта, если это ещё не сделано.

  2. 2.

    Задайте переменные окружения

    Задайте SOLVETHREE_API_KEY и SOLVETHREE_PROXY в окружении процесса PowerShell, используя привычный механизм работы с секретами. Перед запуском убедитесь, что обе переменные заполнены. Ключ API передаётся в заголовке Bearer; ему не место в JSON задачи.

  3. 3.

    Замените пример имени хоста и действия

    Замените accounts.example.com и login на имя хоста и действие, необходимые для вашей интеграции. Укажите имя хоста, а не полный URL. По умолчанию запрос использует Enterprise v3, поэтому поля type и url не нужны.

Создайте задачу один раз, затем опрашивайте её по идентификатору

PowerShell · однократное создание и сохранение идентификатора восстановления
#requires -Version 7.5
$ErrorActionPreference = 'Stop'
$apiBase = 'https://api.solvethree.com/v1'
$headers = @{ Authorization = "Bearer $env:SOLVETHREE_API_KEY"; Accept = 'application/json' }
$taskInput = @{ site = 'accounts.example.com'; action = 'login'; proxy = $env:SOLVETHREE_PROXY; requestId = [guid]::NewGuid().ToString() }
$requestClock = [Diagnostics.Stopwatch]::StartNew()
function Call-TaskApi($Method, $Path, $Payload = $null) {
    $remaining = 180 - $requestClock.Elapsed.TotalSeconds
    if ($remaining -le 0) { throw 'Local deadline reached' }
    $seconds = [int][Math]::Ceiling([Math]::Min(25, $remaining))
    $options = @{ Method = $Method; Uri = "$apiBase$Path"; Headers = $headers;
        ConnectionTimeoutSeconds = $seconds; OperationTimeoutSeconds = $seconds;
        MaximumRetryCount = 0; MaximumRedirection = 0 }
    if ($null -ne $Payload) { $options.Body = $Payload | ConvertTo-Json -Depth 6; $options.ContentType = 'application/json' }
    Invoke-RestMethod @options
}
$taskId = $null
try {
    $result = Call-TaskApi 'POST' '/tasks?waitMs=0' $taskInput
    $taskId = $result.id
    while ($result.status -in @('pending', 'solving')) {
        $escapedId = [uri]::EscapeDataString($taskId)
        $result = Call-TaskApi 'GET' "/tasks/$escapedId`?waitMs=15000"
        if ($result.status -in @('pending', 'solving')) { Start-Sleep -Seconds 1 }
    }
    if ($result.status -ne 'ready') { throw "Task failed: $($result.errorCode)" }
    Write-Host "Ready task: $taskId"
    # Submit $result.solution.token with userAgent/secChUa and the original proxy.
} catch {
    Write-Host "Recovery requestId=$($taskInput.requestId) taskId=$taskId"
    throw
}

Скрипт отправляет один POST-запрос к /v1/tasks?waitMs=0. Последующие запросы — GET для полученного ID с параметром waitMs=15000. При pending и solving цикл продолжается; любой другой статус завершает его.

ConvertTo-Json сериализует хеш-таблицу задачи, избавляя от необходимости вручную экранировать кавычки в JSON или использовать команду оболочки. Перед опросом ID задачи экранируется для URL. Сохраните эти части при адаптации примера.

Stopwatch проверяет локальный лимит в 180 секунд перед каждым вызовом API. Для каждого вызова задаются тайм-ауты подключения и выполнения не более 25 секунд, которые сокращаются по мере исчерпания лимита. Если опрос вернул непромежуточный статус, скрипт не продолжает цикл; после промежуточного статуса он ждёт одну секунду. Лимит предотвращает бесконечный опрос, но не гарантирует остановку точно по истечении заданного времени.

MaximumRetryCount = 0 отключает автоматические повторы HTTP-запросов, а MaximumRedirection = 0 запрещает перенаправления. Используемые здесь параметры тайм-аутов требуют PowerShell 7.5+, а не любой версии PowerShell 7. Эти параметры описаны в справочнике Invoke-RestMethod от Microsoft.

Используйте токен, а не ID задачи

При статусе ready значение reCAPTCHA для отправки находится в $result.solution.token. $taskId лишь идентифицирует задачу solvethree. Пример завершается до отправки прикладного запроса к вашему целевому сайту.

Отправляйте токен вместе с userAgent и secChUa из полученного решения, используя исходный прокси. Не подставляйте посторонние идентификационные данные браузера и не отправляйте токен другому целевому сайту. ready означает, что solvethree сгенерировал решение, но не подтверждает, что целевой сайт принял ваш прикладной запрос.

Invoke-RestMethod выдаёт исключение HTTP или подключения

Запрос к API завершился ошибкой до того, как скрипт смог обработать успешный ответ. Блок catch выводит идентификаторы для восстановления и повторно выбрасывает исходное исключение.

Попробуйте: Проверьте HTTP-статус и подробности ответа, если они доступны. Исправляйте некорректные входные данные, а не повторяйте запрос с ними без изменений. Если результат создания задачи неизвестен, восстановите её, как описано ниже.

Задача возвращает failed

Проверьте и $result.errorCode, и $result.error. Исключение скрипта для завершившейся задачи содержит только код ошибки.

Попробуйте: Прекратите опрос этой задачи и устраните указанную причину. Например, site-unreachable — это ошибка задачи, а не доказательство сбоя самого запроса к API. См. Ошибки CAPTCHA API.

Восстановите запрос с неизвестным результатом, не создавая новую задачу

Тайм-аут не доказывает, что запрос на создание завершился ошибкой. Блок catch выводит requestId и, если он был получен, taskId. Сохраните эти значения.

  1. 1.

    Если у вас есть ID задачи, запросите эту задачу

    Продолжайте с GET /v1/tasks/:id, а не создавайте новую задачу. Достижение локального предельного времени скрипта не означает, что удалённая задача завершилась ошибкой.

  2. 2.

    Если при создании не получен ID задачи, повторите исходный запрос

    Повторно отправьте те же входные данные задачи с тем же requestId, чтобы восстановить существующую задачу. Изменение входных данных при повторном использовании этого ID вызывает конфликт.

  3. 3.

    Не перезапускайте этот скрипт для восстановления

    Новый запуск генерирует новый GUID, а значит, и новый логический запрос. Для работы без участия оператора безопасно сохраняйте исходный requestId и входные данные задачи до POST-запроса, а затем сохраняйте ID задачи, когда он будет получен. При ошибке пример выводит идентификаторы для восстановления, но не сохраняет их на случай потери процесса.

Не записывайте сохранённые входные данные в обычные логи, если URL прокси содержит учётные данные. Для восстановления нужны исходные входные данные, а не ещё одна копия ключа API.

Запустите первую задачу.

Начните с $5 на балансе рабочего пространства.

Создать рабочее пространство
Вызывайте API CAPTCHA из PowerShell · solvethree