Отправка токена CAPTCHA через HTTP-прокси в Go

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

Используйте отдельный HTTP-клиент Go для целевого сайта, настроенный на прокси, выбранный solvethree.SuccessfulProxy. Отправляйте Solution.Token с возвращёнными данными браузера. Держите этот транспорт целевого сайта отдельно от транспорта клиента SDK для API solvethree.

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

Подготовьте задачу

  1. 1.

    Настройте Go SDK и учётные данные

    Используйте официальный модуль solvethree.com/sdk версии v0.1.0 с Go 1.22 или новее. Подробности настройки приведены в справочнике по интеграции с Go. Задайте в SOLVETHREE_API_KEY API-ключ рабочего пространства и храните его на сервере. Задайте в SOLVETHREE_PROXY URL вашего HTTP- или HTTPS-прокси.

  2. 2.

    Настройте сайт перед решением

    В рабочем пространстве должен быть активный профиль для имени целевого хоста. Сначала настройте профиль сайта; передача имени хоста и действия не создаёт профиль.

  3. 3.

    Замените целевой сайт из примера

    Измените accounts.example.com, действие login и конечную точку приложения в соответствии с вашей интеграцией. Site — это имя хоста, а не полный URL. Для reCAPTCHA укажите ровно одно из полей: Proxy или ProxyCandidates; не заполняйте поля задачи Type и URL. Тип reCAPTCHA по умолчанию — Enterprise v3.

Отправляйте через прокси, решивший задачу

Go · отправка через успешный прокси
package main

import (
    "context"
    "fmt"
    "log"
    "os"
    "net/http"
    "net/url"
    "strings"
    "time"
    solvethree "solvethree.com/sdk"
)

func main() {
    client, err := solvethree.NewClient(os.Getenv("SOLVETHREE_API_KEY"), nil)
    if err != nil { log.Fatal(err) }
    ctx, cancel := context.WithTimeout(context.Background(), 180*time.Second)
    defer cancel()
    input := solvethree.TaskRequest{Site: "accounts.example.com", Action: "login", Proxy: os.Getenv("SOLVETHREE_PROXY")}
    result, err := client.Solve(ctx, input, solvethree.SolveOptions{})
    if err != nil { log.Fatal(err) }
    fmt.Println("Ready task:", result.ID)

    proxy, ok := solvethree.SuccessfulProxy(input, result)
    if !ok { log.Fatal("No valid successful proxy") }
    proxyURL, err := url.Parse(proxy)
    if err != nil { log.Fatal(err) }
    transport := http.DefaultTransport.(*http.Transport).Clone()
    transport.Proxy = http.ProxyURL(proxyURL)
    defer transport.CloseIdleConnections()
    targetClient := &http.Client{Transport: transport, Timeout: 30*time.Second,
        CheckRedirect: func(*http.Request, []*http.Request) error { return http.ErrUseLastResponse }}
    request, err := http.NewRequestWithContext(ctx, "POST", "https://accounts.example.com/login",
        strings.NewReader(url.Values{"g-recaptcha-response": {result.Solution.Token}}.Encode()))
    if err != nil { log.Fatal(err) }

    request.Header.Set("User-Agent", result.Solution.UserAgent)
    request.Header.Set("sec-ch-ua", result.Solution.SecChUA)
    request.Header.Set("Content-Type", "application/x-www-form-urlencoded")

    response, err := targetClient.Do(request)
    if err != nil { log.Fatal(err) }
    defer response.Body.Close()
    fmt.Println("Application HTTP status:", response.StatusCode)
    // Inspect the application response to determine whether submission succeeded.

}

SDK решает задачу, но ничего не отправляет на сайт. После решения пример клонирует http.DefaultTransport и задаёт Proxy клона через http.ProxyURL. Этот транспорт использует только отдельный targetClient; транспорт API клиента SDK остаётся неизменным.

Храните учётные данные прокси в компоненте user-info URL. url.Parse сохраняет их для транспорта прокси. Используйте процентное кодирование зарезервированных символов в имени пользователя или пароле вместо ручного разбора URL или отправки учётных данных прокси в заголовке Authorization целевого сайта.

Сохраняйте исходные входные данные задачи и используйте SuccessfulProxy, даже если сейчас передаёте только один прокси. При использовании ProxyCandidates успешный кандидат определяется по Solution.EgressAttempts — индексу в исходном списке с нумерацией от единицы. Вспомогательная функция избавляет от догадок о том, какой кандидат сработал; остановитесь, если она возвращает false. Списки кандидатов принимают не более двенадцати различных URL HTTP- или HTTPS-прокси без пути, строки запроса или фрагмента.

Добавьте заголовки, поля формы и сессию целевого сайта

В примере url.Values используется для кодирования Solution.Token как поля формы g-recaptcha-response, а также задаётся соответствующий тип содержимого. Замените имя поля, если приложение ожидает другое. Добавьте остальные обязательные поля конечной точки, например данные для входа и любое привязанное к сессии значение защиты от CSRF; токен CAPTCHA не является полноценным запросом на вход.

Используйте возвращённые UserAgent и SecChUA, как в примере. Если решение также содержит записи в Headers, добавьте эти возвращённые заголовки в запрос к целевому сайту — пример не копирует эту коллекцию. Используйте согласованные данные браузера и правильный тип содержимого для отправляемого тела запроса.

В примере нет хранилища cookie. Если целевому сайту нужна сессия, создайте хранилище через net/http/cookiejar, подключите его к targetClient.Jar до начала взаимодействия с целевым сайтом и используйте этот клиент повторно для запроса страницы и отправки формы. На протяжении всей сессии используйте один и тот же успешный прокси. Клиент API solvethree не является клиентом сессии целевого сайта.

Прежде чем обращаться к решению, проверьте ошибку решения задачи. Пригодное решение есть только у готовой задачи; поля errorCode и error неуспешной задачи объясняют причину сбоя. При запросе к целевому сервису обработайте ошибку из Do, затем проверьте HTTP-статус и только после этого интерпретируйте тело ответа. Закрывайте response.Body всякий раз, когда Do возвращает ответ без ошибки, в том числе при неуспешном HTTP-ответе.

В примере отключены автоматические перенаправления и выводится статус приложения. Проверьте тело ответа и ожидаемое перенаправление, чтобы определить, приняло ли приложение отправленные данные. Готовая задача — как и сам по себе успешный HTTP-статус — этого не подтверждает.

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

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

Создать рабочее пространство
Отправка токена CAPTCHA через HTTP-прокси в Go · solvethree