Solver captcha di Go: contoh kerja dengan net/http (2026)
Solver captcha di Go tidak membutuhkan package pihak ketiga. net/http dan encoding/json dari standard library sudah mencakup seluruh alurnya: satu POST ke API Scarnox, satu respons JSON, dan satu submit form ke situs. Panduan ini membangun alur tersebut untuk PopularCaptcha, yang saat ini di-solve Scarnox secara proxyless.
Mulai dengan kredit uji coba gratis, tanpa kartu dan jalankan programnya di halaman yang Anda kontrol sebelum Anda memakainya di tempat lain.
Kebutuhan
- Go 1.21 atau yang lebih baru.
- API key Scarnox, dibaca dari environment variable.
- Sitekey dari widget PopularCaptcha di halaman tersebut. Jika Anda butuh bantuan menemukannya, lihat cara mencari sitekey captcha.
Program lengkap
File tunggal ini memecahkan captcha, me-retry kegagalan sementara, dan mengirim token ke form. Simpan sebagai 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"
// Panggilan solve menunggu sampai token siap, jadi timeout-nya panjang.
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 mengulang kegagalan sementara. Solve yang gagal tidak ditagih.
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 menyimpan sesi yang diikat situs ke captcha.
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)
}
Jalankan:
export SCARNOX_API_KEY=scarnox_YOURAPIKEY
go run main.go
Cara potongan-potongannya bekerja
Request. solveCaptcha memasukkan struct ke body JSON yang diharapkan API dan mengatur header Authorization. Awalan Bearer wajib ada.
Timeout. API memblokir sampai token siap, jadi timeout client adalah 185 detik. Jangan mengaturnya lebih rendah, atau Anda akan membatalkan solve yang hampir selesai.
Pengecekan error. API mengembalikan errorId bernilai 0 saat berhasil. Nilai lain disertai errorCode dan errorDescription, dan fungsi ini mengembalikannya sebagai error. Token ada di solution.token.
Pengiriman. Token dimasukkan ke field h-captcha-response, dan g-recaptcha-response menerima nilai yang sama. Kebanyakan situs membaca salah satunya.
Gunakan cookie jar
Banyak halaman signup dan pencarian mengikat captcha ke sebuah sesi. cookiejar pada client situs menyimpan cookie tersebut antara GET yang menampilkan form dan POST yang mengirimnya. Jika Anda melewatkannya, situs bisa menolak token yang sebenarnya valid.
Waktu
Token kedaluwarsa dalam sekitar dua menit, jadi lakukan solve tepat sebelum Anda mengirim. Jangan melakukan solve di awal job yang panjang lalu menunggu. Masa berlaku token captcha menjelaskan cara menentukan ukuran jendela waktunya.
Widget invisible
Jika widget halaman bersifat invisible, atur argumen invisible menjadi true. Request kemudian menyertakan is_invisible: true. Beberapa halaman juga memerlukan fungsi callback yang dipanggil dengan token. Periksa script halaman untuk mencarinya. Panduan captcha invisible mencantumkan polanya.
Konkurensi
Go memudahkan Anda untuk memecahkan banyak captcha sekaligus dengan goroutine. Jaga jumlah solve yang berjalan bersamaan tetap dalam batas yang bisa ditangani akun Anda dan situs target. Satu domain tidak boleh menerima lonjakan request, meskipun solver Anda sanggup mengikutinya. Patuhi robots.txt dan terms situs, dan batasi scraping pada data publik yang memang boleh Anda kumpulkan.
Harga
Scarnox menagih per solve yang berhasil. Solve yang gagal tidak dikenai biaya. Lihat harga terkini untuk tarifnya. Untuk mencoba API, mulai dengan kredit uji coba gratis, tanpa kartu.