Résoudre reCAPTCHA Enterprise avec Go

Par solvethree3 min de lecture

Installez solvethree.com/sdk et appelez Solve avec votre nom d’hôte cible, l’action et le proxy. Le SDK crée la tâche une seule fois et interroge périodiquement son résultat. Votre application envoie ensuite le jeton à la cible.

Sur cette page

Installer et configurer le SDK

Utilisez Go 1.22+. Dans votre module Go, exécutez :

Installer le SDK Go officiel
go get solvethree.com/sdk@v0.1.0
  • Définissez SOLVETHREE_API_KEY sur la clé API de votre espace de travail et SOLVETHREE_PROXY sur l’URL de votre proxy HTTP(S). Conservez ces deux valeurs dans la configuration du serveur.
  • Créez un profil actif pour le nom d’hôte cible dans votre espace de travail. Consultez la configuration du profil de site.
  • Remplacez accounts.example.com et login par le nom d’hôte et l’action utilisés par votre cible. Site accepte un nom d’hôte, sans schéma ni chemin.

Résoudre une tâche

Enregistrez ce code dans main.go et exécutez go run ..

Go · créer une seule fois et interroger périodiquement
package main

import (
    "context"
    "fmt"
    "log"
    "os"
    "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)
    // Submit result.Solution.Token with its browser identity and original proxy.
}

Le contexte limite l’attente locale à 180 secondes. Solve renvoie un TaskResult prêt ou une erreur ; il n’est pas nécessaire de l’entourer d’une autre boucle d’interrogation. Cette requête utilise le mode Enterprise v3 par défaut. Pour la version v3 standard, définissez RecaptchaType: "v3". Ne renseignez pas Type ni URL pour reCAPTCHA.

Envoyer le jeton à votre cible

Envoyez result.Solution.Token dans le champ CAPTCHA de l’application. La valeur result.ID affichée identifie la tâche ; ce n’est pas le jeton.

Utilisez result.Solution.UserAgent comme User-Agent et result.Solution.SecChUA comme sec-ch-ua. Faites passer la requête cible par le proxy ayant permis la résolution, sélectionné avec solvethree.SuccessfulProxy(input, result).

Incluez les autres champs de formulaire, les cookies et la valeur CSRF de l’application, puis vérifiez sa réponse. Le SDK renvoie une solution ; il n’envoie pas la requête à l’application à votre place.

Conserver les identifiants si l’attente est interrompue

L’annulation du contexte arrête l’attente locale, pas le travail distant. *solvethree.Error expose RequestID et TaskID. Récupérez une tâche connue avec GetTask ; si sa création est incertaine, renvoyez exactement les paramètres d’origine avec le même RequestID.

Pour permettre la récupération après un redémarrage du processus, attribuez et enregistrez RequestID avec les paramètres de la tâche avant sa création. Une erreur *TaskFailedError est définitive : examinez son ErrorCode et récupérez la tâche pour obtenir le texte de l’erreur. Corrigez la cause avant de lancer une autre résolution.

Alternative : appeler l’API REST avec la bibliothèque standard

Si vous préférez gérer les appels HTTP vous-même, cette version utilise directement net/http. Choisissez cette version ou l’exemple avec le SDK ci-dessus ; exécuter les deux crée deux tâches. Les structures de réponse présentées ici sont propres à cet exemple autonome ; leurs noms de champs diffèrent donc de ceux des types du SDK.

Go 1.22+ · main.go
package main

import (
    "bytes"
    "context"
    "encoding/json"
    "fmt"
    "net/http"
    "net/url"
    "os"
    "time"
)

type Task struct {
    ID string `json:"id"`
    Status string `json:"status"`
    ErrorCode string `json:"errorCode"`
    Error string `json:"error"`
    Solution struct {
        Token string `json:"token"`
        UserAgent string `json:"userAgent"`
        SecChUa string `json:"secChUa"`
    } `json:"solution"`
}

func main() {
    key, proxy := os.Getenv("SOLVETHREE_API_KEY"), os.Getenv("SOLVETHREE_PROXY")
    if key == "" || proxy == "" { panic("Set SOLVETHREE_API_KEY and SOLVETHREE_PROXY") }
    ctx, cancel := context.WithTimeout(context.Background(), 180*time.Second)
    defer cancel()
    client := &http.Client{Timeout: 30*time.Second}
    api := func(method, path string, body []byte) (Task, error) {
        var task Task
        req, err := http.NewRequestWithContext(ctx, method, "https://api.solvethree.com/v1"+path, bytes.NewReader(body))
        if err != nil { return task, err }
        req.Header.Set("Authorization", "Bearer "+key)
        req.Header.Set("Content-Type", "application/json")
        response, err := client.Do(req)
        if err != nil { return task, err }
        defer response.Body.Close()
        if response.StatusCode < 200 || response.StatusCode >= 300 { return task, fmt.Errorf("API HTTP %d", response.StatusCode) }
        err = json.NewDecoder(response.Body).Decode(&task)
        return task, err
    }
    requestID := fmt.Sprintf("go-%d", time.Now().UnixNano())
    body, err := json.Marshal(map[string]string{
        "site":"accounts.example.com", "action":"login", "proxy":proxy, "requestId":requestID,
    })
    if err != nil { panic(err) }
    // Persist requestID and body before creation if this must survive a restart.
    task, err := api(http.MethodPost, "/tasks?waitMs=0", body)
    if err != nil { panic(fmt.Errorf("request %s: %w", requestID, err)) }
    for task.Status == "pending" || task.Status == "solving" {
        task, err = api(http.MethodGet, "/tasks/"+url.PathEscape(task.ID)+"?waitMs=15000", nil)
        if err != nil { panic(err) }
        if task.Status == "pending" || task.Status == "solving" {
            select { case <-ctx.Done(): panic(ctx.Err()); case <-time.After(time.Second): }
        }
    }
    if task.Status != "ready" { panic("Task failed: "+task.ErrorCode+": "+task.Error) }
    solution := task.Solution
    _ = solution // Apply token and returned browser identity using the same proxy.
    fmt.Println("Ready task:", task.ID)
}

Lancez votre première tâche.

Démarrez avec $5 de crédit dans votre espace de travail.

Créer un espace de travail
Résoudre reCAPTCHA Enterprise avec Go · solvethree