Scarnox · Blog

Captcha solver Go ile: net/http kullanan çalışan örnek (2026)

Go'da captcha solver, üçüncü taraf paket gerektirmez. Standart kütüphanedeki net/http ve encoding/json tüm akışı kapsar: Scarnox API'sine bir POST, bir JSON yanıtı ve siteye bir form gönderimi. Bu rehber bu akışı PopularCaptcha için kurar; Scarnox bugün onu proxysiz olarak çözer.

Ücretsiz deneme kredisiyle, kredi kartı gerekmeden başlayın ve programı başka bir yerde kullanmadan önce sahibi olduğunuz bir sayfada çalıştırın.

Gereksinimler

Tam program

Bu tek dosya captcha'yı çözer, geçici hataları yeniden dener ve token'ı forma gönderir. main.go olarak kaydedin:

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"

// Çözme çağrısı token hazır olana kadar bekler, bu yüzden zaman aşımı uzundur.
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 geçici hataları yeniden dener. Başarısız çözümler ücretlendirilmez.
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, sitenin captcha'yı bağladığı oturumu saklar.
	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)
}

Çalıştırın:

export SCARNOX_API_KEY=scarnox_YOURAPIKEY
go run main.go

Parçalar nasıl birbirine uyar

İstek. solveCaptcha, bir struct'ı API'nin beklediği JSON gövdesine çevirir ve Authorization başlığını ayarlar. Bearer öneki zorunludur.

Zaman aşımı. API token hazır olana kadar bloke olur; bu yüzden istemci zaman aşımı 185 saniyedir. Bunu daha düşük ayarlamayın; yoksa bitmek üzere olan çözümleri iptal edersiniz.

Hata kontrolü. API başarıda errorId değerini 0 döndürür. Başka her değer errorCode ve errorDescription ile gelir ve fonksiyon bunları hata olarak döndürür. Token solution.token içindedir.

Gönderim. Token h-captcha-response alanına gider; g-recaptcha-response alanı da aynı değeri alır. Çoğu site birini ya da diğerini okur.

Birçok kayıt ve arama sayfası captcha'yı bir oturuma bağlar. Site istemcisindeki cookiejar, formu gösteren GET ile formu gönderen POST arasındaki çerezleri korur. Bunu atlarsanız, site geçerli olan bir token'ı reddedebilir.

Zamanlama

Token yaklaşık iki dakikada süresi dolar; bu yüzden çözümü göndermeden hemen önce yapın. Uzun bir işin başında çözüp sonra beklemeyin. Captcha token süresi pencerenin nasıl boyutlandırılacağını açıklar.

Görünmez widget'lar

Sayfadaki widget görünmezse invisible argümanını true yapın. İstek o zaman is_invisible: true içerir. Bazı sayfalar token ile çağrılacak bir JavaScript fonksiyonu da gerektirir. Bunun için sayfanın script'ine bakın. Kalıplar için görünmez captcha rehberine bakın.

Eşzamanlılık

Go, goroutine'lerle birçok captcha'yı aynı anda çözmeyi kolaylaştırır. Eşzamanlı çözüm sayısını hem hesabınızın hem de hedef sitenin kaldırabileceği seviyede tutun. Solver'ınız yetişebilse bile tek bir alan adı bir patlama istek almamalıdır. Sitenin robots.txt dosyasına ve koşullarına uyun ve scraping'i topladığınız izinli herkese açık veriyle sınırlayın.

Fiyatlandırma

Scarnox başarılı her çözüm için ücretlendirir. Başarısız çözümler ücretlendirilmez. Oranlar için fiyatlandırma sayfasına bakın. API'yi denemek için ücretsiz deneme kredisiyle, kredi kartı gerekmeden başlayın.

Sonraki adımlar