Résoudre reCAPTCHA Enterprise avec Java
Utilisez HttpClient de Java pour demander un jeton et Gson pour lire la réponse JSON. Cet exemple appelle l’API REST, attend la fin de la tâche et renvoie la solution reCAPTCHA Enterprise.
Sur cette page
Configurer le site et l’environnement
Utilisez Java 21 ou une version ultérieure. Créez un profil de site actif pour votre cible dans la console, puis définissez SOLVETHREE_API_KEY et SOLVETHREE_PROXY dans l’environnement qui lance Java.
Remplacez accounts.example.com par le nom d’hôte associé à votre profil et login par l’action utilisée par la page. Le champ site accepte un nom d’hôte, sans schéma ni chemin.
Enregistrer et exécuter 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());
}
}Depuis le répertoire contenant Solve.java, téléchargez le JAR Gson, compilez et exécutez :
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 SolveCes commandes utilisent le séparateur de classpath de macOS/Linux, :. Sous Windows, utilisez ; entre le répertoire courant et le JAR Gson.
Lire le jeton dans le résultat
La création utilise waitMs=0. La boucle récupère la tâche correspondant au même identifiant tant que son état est pending ou solving, et s’arrête à ready ou failed. Chaque requête GET peut attendre jusqu’à 15 secondes ; l’appelant dispose d’un délai global de 180 secondes.
Lisez le jeton avec solution.get("token").getAsString(). Utilisez les valeurs userAgent et secChUa renvoyées dans la requête cible, via le même proxy. Le programme affiche l’identifiant de tâche, pas le jeton.
Vérifiez la réponse de la cible après l’envoi. Une tâche prête indique qu’une solution a été générée ; elle ne prouve pas que l’application l’a acceptée.
Erreurs et requêtes interrompues
La fonction utilitaire s’arrête si la réponse HTTP n’indique pas un succès. Une tâche définitivement échouée fournit errorCode et error, et la résolution échouée est remboursée. Consultez la référence des erreurs de l’API pour déterminer ce qu’il faut corriger.
Enregistrez le requestId généré et les paramètres exacts si vous devez permettre la récupération après un redémarrage. Si la création dépasse le délai, renvoyez ces paramètres avec le même identifiant. Si vous disposez déjà d’un identifiant de tâche, récupérez la tâche. Redémarrer ce programme crée un autre UUID et peut créer une autre tâche facturable.
Sources et référence de l’API
Lancez votre première tâche.
Démarrez avec $5 de crédit dans votre espace de travail.