Java'da Selenium ile CAPTCHA API'sini kullanın

solvethree tarafından5 dk okuma

Önce token'ı isteyin, ardından sayfaya gitmeden önce Chrome'u aynı proxy ve döndürülen userAgent ile secChUa değerleriyle yapılandırın. solution.token değerini uygulamanızın CAPTCHA alanına yerleştirin, formu gönderin ve yalnızca hazır bir görevi değil, uygulamanın başarı durumunu bekleyin.

Örnekler, bir Java REST yardımcısı ve Selenium ChromeDriver kullanır. Otomatik CAPTCHA algılama veya tarayıcı eklentisi kullanılmaz.

Bu sayfada

Java projesini ve hedef siteyi hazırlayın

  1. 1.

    Projeyi yapılandırın

    Java 21 veya üzerini kullanın. Maven projesinde Java derleme düzeyini 21 olarak ayarlayın ve Gson 2.15.0 ile org.seleniumhq.selenium:selenium-java:4.52.0 ekleyin. Chrome ve ChromeDriver'ı Selenium Chrome belgelerini kullanarak yapılandırın.

  2. 2.

    Her iki Java dosyasını kaydedin

    İlk örneği src/main/java/Solve.java, ikinciyi ise src/main/java/BrowserSolve.java olarak kaydedin. İkisini aynı pakette tutun; sağlanan dosyalarda paket bildirimi yoktur. BrowserSolve, Solve.main yerine Solve.api çağırır.

  3. 3.

    Site profilini etkinleştirin

    Hedef ana makine adını solvethree konsolunda ayarlayın ve profilinin çalışma alanınız için etkin olduğundan emin olun. Ana makine adı ve eylem göndermek profil oluşturmaz. Site profili kurulumu belgesine bakın.

  4. 4.

    Ortamı ayarlayın

    Aşağıdaki üç ortam değişkenini BrowserSolve çalıştıracak süreçte yapılandırın. Çalışma alanı API anahtarını sayfada veya tarayıcı JavaScript'inde değil, güvenilir Java sürecinizde tutun.

BrowserSolve için ortam değişkenleri
BrowserSolve için ortam değişkenleri
DeğişkenDeğer
SOLVETHREE_API_KEYÇalışma alanı API anahtarınız.
SOLVETHREE_PROXYGömülü kullanıcı adı veya parola, yol, sorgu ya da parça içermeyen, IP izin listeli bir HTTP proxy URL'si.
TARGET_URLFormu içeren uygulama sayfasının tam URL'si.

Bu örnek, Chrome'un proxy URL'si üzerinden proxy kimlik bilgilerini aktarmayı desteklemediği için IP izin listeli bir proxy gerektirir. Aynı proxy değeri hem görev API'sine hem de Chrome'a gönderilir.

API istekleri için Solve.java dosyasını ekleyin

Solve.api, https://api.solvethree.com/v1 adresine kimliği doğrulanmış istekler gönderir, başarılı bir yanıtı ayrıştırmadan önce HTTP durumunu denetler ve her isteği yerel süre sınırında kalan süreyle sınırlar.

Java 21+ · Solve.java (Gson bağımlılığı)
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());
    }
}

Bağımsız main metodu, görev oluşturmayı ve sorgulamayı gösterir. Buradaki accounts.example.com ana makine adı ve login eylemi yer tutucudur. Selenium entegrasyonu için bu dosyayı yardımcı olarak kullanın ve bunun yerine BrowserSolve çalıştırın; her iki main metodunu da çalıştırmak ayrı görevler oluşturur.

Bir reCAPTCHA isteği, site içinde bir ana makine adı, uygulamanın action değeri ve proxy ya da proxyCandidates alanlarından tam olarak birini gerektirir. type veya url eklemeyin. recaptchaType belirtilmezse bu örneklerin kullandığı enterprise-v3 seçilir.

Chrome'u hazır çözümün kimliğiyle başlatın

BrowserSolve, site değerini TARGET_URL üzerinden türetir, görevi oluşturur ve durumu pending veya solving olduğu sürece sorgular. Tarayıcının kullandığı çözümü yalnızca ready durumundaki bir görev sağlar.

Java · hazır bir çözümü Chrome’a aktarma
// Save as BrowserSolve.java beside Solve.java from the Java REST quickstart.
// Add Selenium Java 4.52.0 and Gson 2.15.0 to your Maven dependencies; Java 21+.
import com.google.gson.JsonObject;
import java.net.URI;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.Map;
import java.util.UUID;
import org.openqa.selenium.By;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.support.ui.WebDriverWait;

public class BrowserSolve {
    public static void main(String[] args) throws Exception {
        String target = System.getenv("TARGET_URL");
        String proxy = System.getenv("SOLVETHREE_PROXY");
        URI proxyUri = URI.create(proxy);
        if (proxyUri.getUserInfo() != null) throw new IllegalArgumentException("Use an IP-allowlisted proxy");
        var input = new JsonObject();
        input.addProperty("site", URI.create(target).getHost());
        input.addProperty("action", "login");
        input.addProperty("proxy", proxy);
        input.addProperty("requestId", UUID.randomUUID().toString());
        long deadline = System.nanoTime() + Duration.ofSeconds(180).toNanos();
        var task = Solve.api("/tasks?waitMs=0", input, deadline);
        while (task.get("status").getAsString().matches("pending|solving")) {
            String id = URLEncoder.encode(task.get("id").getAsString(), StandardCharsets.UTF_8);
            task = Solve.api("/tasks/" + id + "?waitMs=15000", null, deadline);
            if (task.get("status").getAsString().matches("pending|solving")) Thread.sleep(1000);
        }
        if (!task.get("status").getAsString().equals("ready")) throw new IllegalStateException("Task failed");
        var solution = task.getAsJsonObject("solution");
        var options = new ChromeOptions();
        options.addArguments("--proxy-server=" + proxy, "--user-agent=" + solution.get("userAgent").getAsString());
        var browser = new ChromeDriver(options);
        try {
            browser.executeCdpCommand("Network.enable", Map.of());
            browser.executeCdpCommand("Network.setExtraHTTPHeaders", Map.of("headers",
                Map.of("sec-ch-ua", solution.get("secChUa").getAsString())));
            browser.get(target);
            var wait = new WebDriverWait(browser, Duration.ofSeconds(20));
            var field = wait.until(driver -> driver.findElement(By.name("g-recaptcha-response")));
            browser.executeScript("arguments[0].value=arguments[1]; arguments[0].dispatchEvent(new Event('input',{bubbles:true}));",
                field, solution.get("token").getAsString());
            browser.findElement(By.cssSelector("button[type=submit]")).click();
            wait.until(driver -> driver.findElement(By.id("success"))); // Your application's success marker.
        } finally { browser.quit(); }
    }
}

Sıralama önemlidir: ChromeOptions proxy'yi ve döndürülen kullanıcı aracısını ayarlar; ardından ChromeDriver, browser.get(target) çağrısından önce döndürülen sec-ch-ua başlığını CDP üzerinden ayarlar. Önce ilgisiz bir kimlikle sayfaya gidip kimliği yalnızca token'ı gönderirken değiştirmeyin.

Bu örnek özellikle tek bir proxy gönderir; böylece Chrome, adaylar arasından seçim yapmadan aynı proxy'yi kullanabilir. Hedef URL'yi, görev için kullanılan ana makine adı ve eylemle tutarlı tutun.

BrowserSolve'u çalıştırmadan önce formu uyarlayın

Tarayıcı örneği, size ait olan ve CAPTCHA yanıt alanı, gönder düğmesi ve başarı öğesi içeren bir formu hedefler. Maven bağımlılıkları sınıf yolundayken BrowserSolve.main metodunu çalıştırmadan önce uygulamaya özgü bu değerleri değiştirin.

  • action: login değerini, uygulamanızın bu gönderim için kullandığı eylemle değiştirin.
  • g-recaptcha-response: formunuzun gerçekten gönderdiği alan adını doğrulayın. Örnek, solution.token değerini atar ve üst öğelere yayılan bir input olayı tetikler.
  • button[type=submit]: bu seçici, amaçlanan formun gönder düğmesini bulmuyorsa değiştirin.
  • success: bu öğe kimliğini, yalnızca mevcut gönderim başarılı olduktan sonra görünen bir durumla değiştirin.

Bir alanı ayarlayıp olay tetiklemek, her durumda çalışan bir CAPTCHA geri çağrısı değildir. Uygulamanızın form mantığı bu alanı veya olayı kullanmıyorsa gönderim adımını gerçek bağlantı mekanizmasına uyarlayın. Giden isteği inceleyerek görev kimliğini veya eski bir token'ı değil, solution.token değerini içerdiğini doğrulayın.

Son WebDriver beklemesi, uygulamanın başarı öğesini kontrol eder. Bu göstergeyi dikkatle seçin: gönderimden önce zaten mevcut olan bir öğe, yeni istek hakkında hiçbir şeyi kanıtlamaz. Hazır bir görev, solvethree'nin bir çözüm ürettiği anlamına gelir; hedefin kabul edip etmediği uygulamanın yanıtıyla belirlenir.

Gereksiz yere başka bir görev oluşturmadan hataları ele alın

API, başarısız bir HTTP yanıtı döndürür.

HTTP yanıtını görev durumundan ayrı kontrol edin. Solve.api, yanıtı başarılı bir yanıt gövdesi olarak işlemeden önce istisna fırlatır.

Şunu deneyin: Yeniden denemeden önce istek hatasının nedenini belirleyin. Değiştirilmemiş geçersiz girdileri tekrar tekrar göndermek yerine istek alanlarını ve etkin site profilini doğrulayın.

Görev failed durumuna geçer.

Görev yanıtındaki errorCode ve error alanlarını okuyun. Solve.java bağımsız örneği bunları gösterse de BrowserSolve'un genel istisnası göstermez.

Şunu deneyin: Bu görevin durumunu sorgulamayı bırakın ve hata işleme kodunuzda bu alanları görünür kılın. Başarısız çözümlerin ücretleri iade edilir; her hatanın krediyle ilgili olduğunu varsaymayın.

Oluşturma işlemi zaman aşımına uğrar veya yerel süre sınırı dolar.

Elinizde zaten bir görev kimliği olup olmadığını veya özgün istek gövdesini ve requestId değerini kaydedip kaydetmediğinizi belirleyin. Bağlantı zaman aşımı, oluşturmanın başarısız olduğunu kanıtlamaz.

Şunu deneyin: Görev kimliğiyle sonucu almayı sürdürün veya aynı requestId ve birebir aynı girdilerle oluşturma işlemini kurtarın. Kurtarma işleminin yeniden başlatmadan sonra da çalışması gerekiyorsa gövdeyi oluşturmadan önce kaydedin; sağlanan main metodunu yeniden çalıştırmak yeni bir requestId üretir.

Görev hazırdır ancak uygulama gönderimi reddeder.

Giden token'ı, eylemi, hedef URL'yi, proxy'yi, kullanıcı aracısını ve sec-ch-ua değerini inceleyin. Uygulamanın yeni atanan alan değerini gerçekten gönderdiğini doğrulayın.

Şunu deneyin: Başka bir çözüm için ödeme yapmadan önce eşleşmeyen değeri veya gönderim bağlantısını düzeltin. Başarılı çözümde kullanılan proxy ile döndürülen kimliği birlikte kullanın.

180 saniyelik API süre sınırı ve 20 saniyelik uygulama beklemesi, örneklerde seçilen yerel sınırlardır; hizmet garantisi değildir. Ek API hata ayrıntıları için CAPTCHA API hataları sayfasına bakın.

İlk görevinizi çalıştırın.

$5 çalışma alanı kredisiyle başlayın.

Çalışma alanı oluşturun
Java'da Selenium ile CAPTCHA API'sini kullanın · solvethree