Resuelve reCAPTCHA Enterprise con Java
Usa HttpClient de Java para solicitar un token y Gson para leer la respuesta JSON. Este ejemplo llama a la API REST, espera a que finalice la tarea y devuelve la solución de reCAPTCHA Enterprise.
En esta página
Configura el sitio y el entorno
Usa Java 21 o posterior. Crea un perfil de sitio activo para tu destino en la consola y, después, establece SOLVETHREE_API_KEY y SOLVETHREE_PROXY en el entorno que inicia Java.
Sustituye accounts.example.com por el nombre de host de tu perfil y login por la acción que utiliza la página. El campo site acepta un nombre de host, sin esquema ni ruta.
Guarda y ejecuta Solve.java
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.*;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.UUID;
public class Solve {
static final HttpClient HTTP = HttpClient.newBuilder()
.connectTimeout(Duration.ofSeconds(15)).build();
static final String KEY = System.getenv("SOLVETHREE_API_KEY");
static JsonObject api(String path, JsonObject body, long deadline) throws Exception {
long remaining = deadline - System.nanoTime();
if (remaining <= 0) throw new IllegalStateException("Keep the task ID and resume polling");
var builder = HttpRequest.newBuilder(URI.create("https://api.solvethree.com/v1" + path))
.timeout(Duration.ofNanos(Math.min(remaining, Duration.ofSeconds(30).toNanos())))
.header("Authorization", "Bearer " + KEY)
.header("Content-Type", "application/json");
if (body == null) builder.GET();
else builder.POST(HttpRequest.BodyPublishers.ofString(body.toString()));
var response = HTTP.send(builder.build(), HttpResponse.BodyHandlers.ofString());
if (response.statusCode() < 200 || response.statusCode() >= 300)
throw new IllegalStateException("API HTTP " + response.statusCode());
return JsonParser.parseString(response.body()).getAsJsonObject();
}
public static void main(String[] args) throws Exception {
String proxy = System.getenv("SOLVETHREE_PROXY");
if (KEY == null || proxy == null) throw new IllegalArgumentException("Set the API key and proxy");
var input = new JsonObject();
input.addProperty("site", "accounts.example.com");
input.addProperty("action", "login");
input.addProperty("proxy", proxy);
input.addProperty("requestId", UUID.randomUUID().toString());
// Save input before creation if the task must be recovered after restart.
long deadline = System.nanoTime() + Duration.ofSeconds(180).toNanos();
var task = api("/tasks?waitMs=0", input, deadline);
while (task.get("status").getAsString().equals("pending") || task.get("status").getAsString().equals("solving")) {
String id = URLEncoder.encode(task.get("id").getAsString(), StandardCharsets.UTF_8);
task = api("/tasks/" + id + "?waitMs=15000", null, deadline);
if (task.get("status").getAsString().equals("pending") || task.get("status").getAsString().equals("solving"))
Thread.sleep(1000);
}
if (!task.get("status").getAsString().equals("ready"))
throw new IllegalStateException("Task failed: " + task.get("errorCode")
+ ": " + task.get("error"));
var solution = task.getAsJsonObject("solution");
// Submit solution.token with userAgent/secChUa and the original proxy.
System.out.println("Ready task: " + task.get("id").getAsString());
}
}Desde el directorio que contiene Solve.java, descarga el JAR de Gson, compila y ejecuta:
curl --fail --location --output gson-2.15.0.jar \
https://repo.maven.apache.org/maven2/com/google/code/gson/gson/2.15.0/gson-2.15.0.jar
javac -cp gson-2.15.0.jar Solve.java
java -cp .:gson-2.15.0.jar SolveEstos comandos usan el separador de classpath de macOS/Linux, :. En Windows, usa ; entre el directorio actual y el JAR de Gson.
Lee el token del resultado
La creación usa waitMs=0. El bucle consulta el mismo ID de tarea mientras el estado sea pending o solving y se detiene en ready o failed. Cada GET puede esperar hasta 15 segundos; el cliente tiene un límite de tiempo total de 180 segundos.
Lee el token con solution.get("token").getAsString(). Usa los valores devueltos userAgent y secChUa en la solicitud de destino, a través del mismo proxy. El programa imprime el ID de la tarea, no el token.
Comprueba la respuesta del destino después del envío. Una tarea lista indica que se generó una solución; no demuestra que la aplicación la haya aceptado.
Errores y solicitudes interrumpidas
La función auxiliar se detiene si la respuesta HTTP no indica éxito. Una tarea con un fallo definitivo devuelve errorCode y error, y la resolución fallida se reembolsa. Usa la referencia de errores de la API para decidir qué corregir.
Guarda el requestId generado y los datos de entrada exactos si necesitas recuperar la tarea tras un reinicio. Si la creación agota el tiempo de espera, vuelve a enviar esos datos con el mismo ID. Si ya tienes un ID de tarea, recupérala. Reiniciar este programa crea otro UUID y puede crear otra tarea facturable.
Fuentes y referencia de la API
Ejecuta tu primera tarea.
Empieza con $5 de crédito en tu espacio de trabajo.