Солвер капчі на Go: робочий приклад з net/http (2026)
Солверу капчі на Go не потрібні сторонні пакети. Стандартні net/http і encoding/json покривають увесь потік: один POST до API Scarnox, одна JSON-відповідь і одна відправка форми на сайт. Цей посібник будує такий потік для PopularCaptcha, яку Scarnox сьогодні розв'язує в режимі proxyless.
Почніть з безкоштовного пробного кредиту, картка не потрібна і запустіть програму на сторінці, якою володієте, перш ніж використовувати її деінде.
Вимоги
- Go 1.21 або новіший.
- Ключ API Scarnox, який зчитується зі змінної середовища.
- Sitekey віджета PopularCaptcha на сторінці. Якщо потрібна допомога з пошуком, дивіться як знайти sitekey капчі.
Повна програма
Цей один файл розв'язує капчу, повторює тимчасові збої і відправляє токен у форму. Збережіть його як main.go:
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"log"
"net/http"
"net/http/cookiejar"
"net/url"
"os"
"time"
)
const apiURL = "https://api.scarnox.com/api/tasks/create"
// Виклик розв'язання блокується, доки токен не буде готовий, тому таймаут довгий.
var apiClient = &http.Client{Timeout: 185 * time.Second}
type createRequest struct {
CaptchaType string `json:"captcha_type"`
SiteKey string `json:"site_key"`
SiteURL string `json:"site_url"`
IsInvisible bool `json:"is_invisible,omitempty"`
}
type createResponse struct {
ErrorID int `json:"errorId"`
ErrorCode string `json:"errorCode"`
ErrorDescription string `json:"errorDescription"`
Solution struct {
Token string `json:"token"`
} `json:"solution"`
}
func solveCaptcha(apiKey, sitekey, pageURL string, invisible bool) (string, error) {
body, err := json.Marshal(createRequest{
CaptchaType: "PopularCaptchaTaskProxyless",
SiteKey: sitekey,
SiteURL: pageURL,
IsInvisible: invisible,
})
if err != nil {
return "", err
}
req, err := http.NewRequest(http.MethodPost, apiURL, bytes.NewReader(body))
if err != nil {
return "", err
}
req.Header.Set("Authorization", "Bearer "+apiKey)
req.Header.Set("Content-Type", "application/json")
resp, err := apiClient.Do(req)
if err != nil {
return "", err
}
defer resp.Body.Close()
raw, err := io.ReadAll(resp.Body)
if err != nil {
return "", err
}
var out createResponse
if err := json.Unmarshal(raw, &out); err != nil {
return "", fmt.Errorf("HTTP %d, response was not JSON: %s", resp.StatusCode, raw)
}
if out.ErrorID != 0 {
return "", fmt.Errorf("%s: %s", out.ErrorCode, out.ErrorDescription)
}
return out.Solution.Token, nil
}
// solveWithRetry повторює тимчасові збої. Невдалі розв'язання не тарифікуються.
func solveWithRetry(apiKey, sitekey, pageURL string, attempts int) (string, error) {
var lastErr error
for i := 1; i <= attempts; i++ {
token, err := solveCaptcha(apiKey, sitekey, pageURL, false)
if err == nil {
return token, nil
}
lastErr = err
log.Printf("attempt %d failed: %v", i, err)
time.Sleep(time.Duration(i) * time.Second)
}
return "", lastErr
}
func main() {
apiKey := os.Getenv("SCARNOX_API_KEY")
if apiKey == "" {
log.Fatal("set SCARNOX_API_KEY")
}
const pageURL = "https://example.com/signup"
const sitekey = "YOUR-SITEKEY-UUID"
token, err := solveWithRetry(apiKey, sitekey, pageURL, 3)
if err != nil {
log.Fatal(err)
}
// Cookie jar зберігає сесію, до якої сайт прив'язує капчу.
jar, err := cookiejar.New(nil)
if err != nil {
log.Fatal(err)
}
site := &http.Client{Jar: jar, Timeout: 60 * time.Second}
form := url.Values{}
form.Set("email", "you@example.com")
form.Set("h-captcha-response", token)
form.Set("g-recaptcha-response", token)
resp, err := site.PostForm(pageURL, form)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
fmt.Println("Status:", resp.Status)
}
Запуск:
export SCARNOX_API_KEY=scarnox_YOURAPIKEY
go run main.go
Як частини складаються разом
Запит. solveCaptcha перетворює структуру на JSON-тіло, яке очікує API, і встановлює заголовок Authorization. Префікс Bearer обов'язковий.
Таймаут. API блокується, доки токен не буде готовий, тому таймаут клієнта — 185 секунд. Не встановлюйте менше, інакше скасуєте розв'язання, які мали от-от завершитися.
Перевірка помилки. API повертає errorId зі значенням 0 при успіху. Будь-яке інше значення супроводжується errorCode і errorDescription, і функція повертає їх як помилку. Токен лежить у solution.token.
Відправка. Токен іде в поле h-captcha-response, а g-recaptcha-response отримує те саме значення. Більшість сайтів читають одне з них.
Використовуйте cookie jar
Багато сторінок реєстрації та пошуку прив'язують капчу до сесії. cookiejar на клієнті сайту зберігає ці cookie між GET, який показує форму, і POST, який її відправляє. Якщо його пропустити, сайт може відхилити токен, який інакше був би дійсним.
Час
Токен спливає приблизно за дві хвилини, тож розв'язуйте безпосередньо перед відправкою. Не розв'язуйте на початку довгого завдання і не чекайте. Посібник про термін дії токена капчі пояснює, як розрахувати вікно.
Невидимі віджети
Якщо віджет на сторінці невидимий, встановіть аргумент invisible зі значенням true. Тоді запит містить is_invisible: true. Деякі сторінки також потребують колбеку, який викликається з токеном. Перевірте скрипт сторінки на його наявність. Посібник про невидиму капчу перелічує патерни.
Паралельність
У Go легко розв'язувати багато капч одночасно через горутини. Тримайте кількість одночасних розв'язань у межах того, що витримують ваш обліковий запис і цільовий сайт. Один домен не повинен отримувати сплеск запитів, навіть якщо ваш солвер встигає. Дотримуйтесь robots.txt і умов сайту та обмежуйтесь публічними даними, які вам дозволено збирати.
Ціни
Scarnox тарифікує за кожне успішне розв'язання. Невдалі розв'язання безкоштовні. Тарифи дивіться на сторінці цін. Щоб спробувати API, почніть з безкоштовного пробного кредиту, картка не потрібна.