Envía un token de CAPTCHA a través de un proxy HTTP en Go

Por solvethree4 min de lectura

Usa un cliente HTTP de Go independiente para el sitio web de destino, configurado con el proxy seleccionado por solvethree.SuccessfulProxy. Envía Solution.Token con la identidad del navegador devuelta. Mantén este transporte del destino separado del transporte de la API de solvethree del cliente del SDK.

En esta página

Prepara la tarea

  1. 1.

    Configura el SDK de Go y las credenciales

    Usa el módulo oficial solvethree.com/sdk, versión v0.1.0, con Go 1.22 o posterior. La referencia de integración con Go incluye los detalles de configuración. Asigna a SOLVETHREE_API_KEY la clave de API de tu espacio de trabajo y mantenla en el servidor. Asigna a SOLVETHREE_PROXY la URL de tu proxy HTTP o HTTPS.

  2. 2.

    Configura el sitio antes de resolver

    El espacio de trabajo necesita un perfil activo para el nombre de host de destino. Configura primero el perfil del sitio; enviar un nombre de host y una acción no crea uno.

  3. 3.

    Sustituye el destino del ejemplo

    Cambia accounts.example.com, la acción login y el endpoint de la aplicación para adaptarlos a tu integración. Site es un nombre de host, no una URL completa. Para reCAPTCHA, proporciona exactamente uno de los campos Proxy o ProxyCandidates; no rellenes los campos Type ni URL de la tarea. El tipo de reCAPTCHA predeterminado es Enterprise v3.

Realiza el envío a través del proxy que resolvió la tarea

Go · enviar a través del proxy que tuvo éxito
package main

import (
    "context"
    "fmt"
    "log"
    "os"
    "net/http"
    "net/url"
    "strings"
    "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)

    proxy, ok := solvethree.SuccessfulProxy(input, result)
    if !ok { log.Fatal("No valid successful proxy") }
    proxyURL, err := url.Parse(proxy)
    if err != nil { log.Fatal(err) }
    transport := http.DefaultTransport.(*http.Transport).Clone()
    transport.Proxy = http.ProxyURL(proxyURL)
    defer transport.CloseIdleConnections()
    targetClient := &http.Client{Transport: transport, Timeout: 30*time.Second,
        CheckRedirect: func(*http.Request, []*http.Request) error { return http.ErrUseLastResponse }}
    request, err := http.NewRequestWithContext(ctx, "POST", "https://accounts.example.com/login",
        strings.NewReader(url.Values{"g-recaptcha-response": {result.Solution.Token}}.Encode()))
    if err != nil { log.Fatal(err) }

    request.Header.Set("User-Agent", result.Solution.UserAgent)
    request.Header.Set("sec-ch-ua", result.Solution.SecChUA)
    request.Header.Set("Content-Type", "application/x-www-form-urlencoded")

    response, err := targetClient.Do(request)
    if err != nil { log.Fatal(err) }
    defer response.Body.Close()
    fmt.Println("Application HTTP status:", response.StatusCode)
    // Inspect the application response to determine whether submission succeeded.

}

El SDK resuelve la tarea, pero no envía nada al sitio web. Tras resolverla, el ejemplo clona http.DefaultTransport y configura el Proxy del clon mediante http.ProxyURL. Solo el cliente independiente targetClient usa ese transporte; el transporte de la API del cliente del SDK no cambia.

Mantén las credenciales del proxy en el componente de información de usuario de la URL. url.Parse las conserva para el transporte del proxy. Codifica con porcentajes los caracteres reservados del nombre de usuario o la contraseña, en lugar de dividir la URL manualmente o enviar las credenciales del proxy como una cabecera Authorization al destino.

Conserva los datos de entrada originales de la tarea y usa SuccessfulProxy aunque actualmente solo proporciones un proxy. Con ProxyCandidates, el candidato que funcionó se identifica mediante Solution.EgressAttempts, un índice que empieza en uno y hace referencia a la lista original. La función auxiliar evita tener que adivinar qué candidato funcionó; detente si devuelve false. Las listas de candidatos admiten como máximo doce URL de proxy HTTP o HTTPS distintas, sin ruta, consulta ni fragmento.

Incluye las cabeceras, los campos del formulario y la sesión del destino

El ejemplo usa url.Values para codificar Solution.Token como datos de formulario en g-recaptcha-response y establece el tipo de contenido correspondiente. Sustituye ese nombre de campo si tu aplicación espera otro. Añade los demás campos obligatorios del endpoint, como los datos de inicio de sesión y cualquier valor anti-CSRF vinculado a la sesión; un token CAPTCHA no constituye una solicitud de inicio de sesión completa.

Usa los valores devueltos de UserAgent y SecChUA, como hace el ejemplo. Si la solución también proporciona entradas en Headers, aplica también esas cabeceras devueltas a la solicitud al destino: el ejemplo no copia esa colección. Mantén una identidad de navegador coherente y el tipo de contenido correcto para el cuerpo que envías.

El ejemplo no tiene un almacén de cookies. Si el destino requiere una sesión, crea uno con net/http/cookiejar, asígnalo a targetClient.Jar antes de iniciar el flujo con el destino y reutiliza ese cliente para la solicitud de la página y el envío del formulario. Usa el mismo proxy que funcionó durante toda esa sesión. El cliente de la API de solvethree no es el cliente de sesión del destino.

Comprueba el error de resolución antes de acceder a la solución. Solo una tarea lista tiene una solución utilizable; los campos errorCode y error de una tarea fallida explican el fallo. Para la solicitud al destino, gestiona el error de Do y después comprueba el estado HTTP antes de interpretar el cuerpo de la respuesta. Cierra response.Body siempre que Do devuelva una respuesta sin error, incluidas las respuestas HTTP no satisfactorias.

El ejemplo desactiva las redirecciones automáticas e imprime el estado de la aplicación. Inspecciona el cuerpo de la respuesta y cualquier redirección esperada para determinar si la aplicación aceptó el envío. Una tarea lista, o un estado HTTP satisfactorio por sí solo, no confirma ese resultado.

Ejecuta tu primera tarea.

Empieza con $5 de crédito en tu espacio de trabajo.

Crear un espacio de trabajo
Envía un token de CAPTCHA a través de un proxy HTTP en Go · solvethree