Scarnox · Blog

Go में captcha solver: net/http के साथ काम करने वाला उदाहरण (2026)

Go में captcha solver को किसी third-party package की ज़रूरत नहीं है। Standard library के net/http और encoding/json पूरा flow कवर कर देते हैं: Scarnox API पर एक POST, एक JSON response, और site पर एक form submit। यह guide PopularCaptcha के लिए यही flow बनाती है, जिसे Scarnox आज proxyless आधार पर solve करता है।

मुफ़्त ट्रायल क्रेडिट से शुरू करें, कार्ड की ज़रूरत नहीं और program को कहीं और इस्तेमाल करने से पहले अपने किसी page पर चलाएँ।

ज़रूरतें

पूरा program

यह एक file captcha solve करती है, अस्थायी विफलताओं को retry करती है, और token को form में submit करती है। इसे 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"

// solve call token तैयार होने तक रुकती है, इसलिए timeout लंबा है।
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 अस्थायी विफलताओं को retry करता है। विफल solves का चार्ज नहीं लगता।
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 वही session रखता है जिससे site 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)
}

चलाएँ:

export SCARNOX_API_KEY=scarnox_YOURAPIKEY
go run main.go

ये हिस्से कैसे जुड़ते हैं

Request। solveCaptcha एक struct को उस JSON body में बदलता है जिसकी API उम्मीद करती है, और Authorization header सेट करता है। Bearer prefix ज़रूरी है।

Timeout। API तब तक रुकती है जब तक token तैयार न हो, इसलिए client timeout 185 सेकंड है। इसे कम न करें, वरना आप उन solves को रद्द कर देंगे जो लगभग पूरे होने वाले थे।

Error जाँच। API सफलता पर errorId को 0 लौटाती है। कोई और मान errorCode और errorDescription के साथ आता है, और function उन्हें error के रूप में लौटाता है। Token solution.token पर है।

Submit। Token h-captcha-response field में जाता है, और g-recaptcha-response को भी वही value मिलती है। ज़्यादातर sites इनमें से कोई एक पढ़ती हैं।

कई sign-up और search pages captcha को session से जोड़ती हैं। Site client पर cookiejar उन cookies को उस GET और उस POST के बीच रखता है जो form दिखाता और submit करता है। इसे छोड़ने पर site ऐसे token को भी reject कर सकती है जो अन्यथा वैध था।

समय

Token लगभग दो मिनट में expire होता है, इसलिए solve ठीक submit से पहले करें। लंबे job की शुरुआत में solve करके फिर इंतज़ार न करें। captcha token expiry बताती है कि window का आकार कैसे तय करें।

Invisible widgets

अगर page का widget invisible है, तो invisible argument को true सेट करें। तब request में is_invisible: true जुड़ जाता है। कुछ pages को token के साथ बुलाए जाने वाले एक JavaScript function की भी ज़रूरत होती है। Page की script में उसे खोजें। invisible captcha guide पैटर्न सूचीबद्ध करती है।

Concurrency

Go में goroutines के साथ कई captcha एक साथ solve करना आसान है। Concurrent solves की संख्या को अपने account और target site जितना संभाल सकें उतना रखें। एक domain पर अचानक burst न आए, भले ही आपका solver उसे संभाल ले। Robots.txt और terms का सम्मान करें, और scraping को केवल उसी public data तक सीमित रखें जिसे इकट्ठा करने की आपको अनुमति है।

कीमत

Scarnox हर सफल solve पर बिल करता है। विफल solves मुफ़्त हैं। दरों के लिए मौजूदा pricing देखें। API आज़माने के लिए मुफ़्त ट्रायल क्रेडिट से शुरू करें, कार्ड की ज़रूरत नहीं।

अगले कदम