Отправка токена CAPTCHA через HTTP-прокси в Go
Используйте отдельный HTTP-клиент Go для целевого сайта, настроенный на прокси, выбранный solvethree.SuccessfulProxy. Отправляйте Solution.Token с возвращёнными данными браузера. Держите этот транспорт целевого сайта отдельно от транспорта клиента SDK для API solvethree.
На этой странице
Подготовьте задачу
- 1.
Настройте Go SDK и учётные данные
Используйте официальный модуль
solvethree.com/sdkверсииv0.1.0с Go 1.22 или новее. Подробности настройки приведены в справочнике по интеграции с Go. Задайте вSOLVETHREE_API_KEYAPI-ключ рабочего пространства и храните его на сервере. Задайте вSOLVETHREE_PROXYURL вашего HTTP- или HTTPS-прокси. - 2.
Настройте сайт перед решением
В рабочем пространстве должен быть активный профиль для имени целевого хоста. Сначала настройте профиль сайта; передача имени хоста и действия не создаёт профиль.
- 3.
Замените целевой сайт из примера
Измените
accounts.example.com, действиеloginи конечную точку приложения в соответствии с вашей интеграцией.Site— это имя хоста, а не полный URL. Для reCAPTCHA укажите ровно одно из полей:ProxyилиProxyCandidates; не заполняйте поля задачиTypeиURL. Тип reCAPTCHA по умолчанию — Enterprise v3.
Отправляйте через прокси, решивший задачу
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-статус — этого не подтверждает.
Источники и справочник API
Запустите первую задачу.
Начните с $5 на балансе рабочего пространства.