Cara menyelesaikan Captcha di Browser4 dengan integrasi CapSolver

Anh Tuan
Data Science Expert
21-Jan-2026

Untuk otomatisasi web, Browser4 (dari PulsarRPA) telah muncul sebagai mesin browser yang cepat, aman korutin, yang dirancang untuk ekstraksi data berkekuatan AI. Dengan kemampuan yang mendukung 100k-200k kunjungan halaman kompleks per mesin per hari, Browser4 dirancang untuk skala yang serius. Namun, ketika mengekstrak data dari situs web yang dilindungi, tantangan CAPTCHA menjadi penghalang yang signifikan.
CapSolver memberikan pelengkap yang sempurna untuk kemampuan otomatisasi Browser4, memungkinkan agen Anda untuk menavigasi halaman yang dilindungi CAPTCHA secara mulus. Integrasi ini menggabungkan otomatisasi browser berkecepatan tinggi Browser4 dengan solusi CAPTCHA yang unggul di industri.
Apa itu Browser4?
Browser4 adalah kerangka kerja otomatisasi browser berkinerja tinggi yang dibangun dalam Kotlin. Dirancang untuk aplikasi AI yang memerlukan kemampuan agen mandiri, throughput ekstrem, dan ekstraksi data hibrid yang menggabungkan LLM, algoritma machine learning, dan pendekatan berbasis selector.
Fitur Utama Browser4
- Throughput Ekstrem: 100k-200k kunjungan halaman kompleks per mesin per hari
- Aman Korutin: Dibangun dengan korutin Kotlin untuk pemrosesan paralel yang efisien
- Agen Berkekuatan AI: Agen browser mandiri yang mampu berpikir dan menjalankan tugas multi-langkah
- Ekstraksi Hibrid: Menggabungkan kecerdasan LLM, algoritma ML, dan selector CSS/XPath
- Pertanyaan X-SQL: Sintaks SQL yang diperluas untuk ekstraksi data kompleks
- Fitur Anti-Bot: Rotasi profil, dukungan proxy, dan penjadwalan yang tangguh
Metode API Inti
| Metode | Deskripsi |
|---|---|
session.open(url) |
Memuat halaman dan mengembalikan PageSnapshot |
session.parse(page) |
Mengonversi snapshot menjadi dokumen di memori |
driver.selectFirstTextOrNull(selector) |
Mengambil teks dari DOM yang sedang berjalan |
driver.evaluate(script) |
Menjalankan JavaScript di browser |
session.extract(document, fieldMap) |
Memetakan selector CSS ke bidang yang terstruktur |
Apa itu CapSolver?
CapSolver adalah layanan penyelesaian CAPTCHA yang terkemuka yang menyediakan solusi berkekuatan AI untuk melewati berbagai tantangan CAPTCHA. Dengan dukungan untuk berbagai jenis CAPTCHA dan respons yang cepat, CapSolver terintegrasi secara mulus ke dalam alur kerja otomatis.
Jenis CAPTCHA yang Didukung
- reCAPTCHA v2 (Gambar & Tidak Terlihat)
- reCAPTCHA v3
- Cloudflare Turnstile
- Cloudflare Challenge (5s)
- AWS WAF
- Dan banyak lagi...
Mengapa Mengintegrasikan CapSolver dengan Browser4?
Ketika membangun otomatisasi Browser4 yang berinteraksi dengan situs web yang dilindungi—baik untuk ekstraksi data, pemantauan harga, atau penelitian pasar—tantangan CAPTCHA menjadi penghalang yang signifikan. Berikut adalah alasan mengapa integrasi ini penting:
- Ekstraksi Throughput Tanpa Gangguan: Pertahankan 100k+ kunjungan halaman per hari tanpa blokir CAPTCHA
- Operasi yang Dapat Diperluas: Menangani CAPTCHA di seluruh eksekusi korutin paralel
- Alur Kerja yang Lancar: Menyelesaikan CAPTCHA sebagai bagian dari pipeline ekstraksi Anda
- Efisien Biaya: Bayar hanya untuk CAPTCHA yang berhasil diselesaikan
- Tingkat Keberhasilan Tinggi: Akurasi terkemuka di industri untuk semua jenis CAPTCHA yang didukung
Instalasi
Prasyarat
- Java 17 atau lebih tinggi
- Maven 3.6+ atau Gradle
- Kunci API CapSolver

Menambahkan Dependency
Maven (pom.xml):
xml
<dependencies>
<!-- Browser4/PulsarRPA -->
<dependency>
<groupId>ai.platon.pulsar</groupId>
<artifactId>pulsar-boot</artifactId>
<version>2.2.0</version>
</dependency>
<!-- Klien HTTP untuk CapSolver -->
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>4.12.0</version>
</dependency>
<!-- Pemrosesan JSON -->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.10.1</version>
</dependency>
<!-- Korutin Kotlin -->
<dependency>
<groupId>org.jetbrains.kotlinx</groupId>
<artifactId>kotlinx-coroutines-core</artifactId>
<version>1.8.0</version>
</dependency>
</dependencies>
Gradle (build.gradle.kts):
kotlin
dependencies {
implementation("ai.platon.pulsar:pulsar-boot:2.2.0")
implementation("com.squareup.okhttp3:okhttp:4.12.0")
implementation("com.google.code.gson:gson:2.10.1")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.0")
}
Pengaturan Lingkungan
Buat file application.properties:
properties
# Konfigurasi CapSolver
CAPSOLVER_API_KEY=kunci_api_capsolver_anda
# Konfigurasi LLM (opsional, untuk ekstraksi AI)
OPENROUTER_API_KEY=kunci_api_openrouter_anda
# Konfigurasi Proxy (opsional)
PROXY_ROTATION_URL=url_proxy_anda
Membuat Layanan CapSolver untuk Browser4
Berikut adalah layanan Kotlin yang dapat digunakan kembali yang mengintegrasikan CapSolver dengan Browser4:
Layanan Dasar CapSolver
kotlin
import com.google.gson.Gson
import com.google.gson.JsonObject
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.RequestBody.Companion.toRequestBody
import kotlinx.coroutines.delay
import java.util.concurrent.TimeUnit
data class TaskResult(
val gRecaptchaResponse: String? = null,
val token: String? = null,
val cookies: List<Map<String, String>>? = null,
val userAgent: String? = null
)
class CapSolverService(private val apiKey: String) {
private val client = OkHttpClient.Builder()
.connectTimeout(30, TimeUnit.SECONDS)
.readTimeout(30, TimeUnit.SECONDS)
.build()
private val gson = Gson()
private val baseUrl = "https://api.capsolver.com"
private val jsonMediaType = "application/json".toMediaType()
private suspend fun createTask(taskData: Map<String, Any>): String {
val payload = mapOf(
"clientKey" to apiKey,
"task" to taskData
)
val request = Request.Builder()
.url("$baseUrl/createTask")
.post(gson.toJson(payload).toRequestBody(jsonMediaType))
.build()
val response = client.newCall(request).execute()
val result = gson.fromJson(response.body?.string(), JsonObject::class.java)
if (result.get("errorId").asInt != 0) {
throw Exception("Kesalahan CapSolver: ${result.get("errorDescription").asString}")
}
return result.get("taskId").asString
}
private suspend fun getTaskResult(taskId: String, maxAttempts: Int = 60): TaskResult {
val payload = mapOf(
"clientKey" to apiKey,
"taskId" to taskId
)
repeat(maxAttempts) {
delay(2000)
val request = Request.Builder()
.url("$baseUrl/getTaskResult")
.post(gson.toJson(payload).toRequestBody(jsonMediaType))
.build()
val response = client.newCall(request).execute()
val result = gson.fromJson(response.body?.string(), JsonObject::class.java)
when (result.get("status")?.asString) {
"ready" -> {
val solution = result.getAsJsonObject("solution")
return TaskResult(
gRecaptchaResponse = solution.get("gRecaptchaResponse")?.asString,
token = solution.get("token")?.asString,
userAgent = solution.get("userAgent")?.asString
)
}
"failed" -> throw Exception("Tugas gagal: ${result.get("errorDescription")?.asString}")
}
}
throw Exception("Waktu tunggu solusi CAPTCHA habis")
}
suspend fun solveReCaptchaV2(websiteUrl: String, websiteKey: String): String {
val taskId = createTask(mapOf(
"type" to "ReCaptchaV2TaskProxyLess",
"websiteURL" to websiteUrl,
"websiteKey" to websiteKey
))
val result = getTaskResult(taskId)
return result.gRecaptchaResponse ?: throw Exception("Tidak ada gRecaptchaResponse dalam solusi")
}
suspend fun solveReCaptchaV3(
websiteUrl: String,
websiteKey: String,
pageAction: String = "submit"
): String {
val taskId = createTask(mapOf(
"type" to "ReCaptchaV3TaskProxyLess",
"websiteURL" to websiteUrl,
"websiteKey" to websiteKey,
"pageAction" to pageAction
))
val result = getTaskResult(taskId)
return result.gRecaptchaResponse ?: throw Exception("Tidak ada gRecaptchaResponse dalam solusi")
}
suspend fun solveTurnstile(
websiteUrl: String,
websiteKey: String,
action: String? = null,
cdata: String? = null
): String {
val taskData = mutableMapOf(
"type" to "AntiTurnstileTaskProxyLess",
"websiteURL" to websiteUrl,
"websiteKey" to websiteKey
)
// Tambahkan metadata opsional
if (action != null || cdata != null) {
val metadata = mutableMapOf<String, String>()
action?.let { metadata["action"] = it }
cdata?.let { metadata["cdata"] = it }
taskData["metadata"] = metadata
}
val taskId = createTask(taskData)
val result = getTaskResult(taskId)
return result.token ?: throw Exception("Tidak ada token dalam solusi")
}
suspend fun checkBalance(): Double {
val payload = mapOf("clientKey" to apiKey)
val request = Request.Builder()
.url("$baseUrl/getBalance")
.post(gson.toJson(payload).toRequestBody(jsonMediaType))
.build()
val response = client.newCall(request).execute()
val result = gson.fromJson(response.body?.string(), JsonObject::class.java)
return result.get("balance")?.asDouble ?: 0.0
}
}
Menyelesaikan Berbagai Jenis CAPTCHA
reCAPTCHA v2 dengan Browser4
kotlin
import ai.platon.pulsar.context.PulsarContexts
import ai.platon.pulsar.skeleton.session.PulsarSession
import kotlinx.coroutines.runBlocking
class ReCaptchaV2Extractor(
private val capSolver: CapSolverService
) {
suspend fun extractWithCaptcha(targetUrl: String, siteKey: String): Map<String, Any?> {
println("Menyelesaikan reCAPTCHA v2...")
// Selesaikan CAPTCHA terlebih dahulu
val token = capSolver.solveReCaptchaV2(targetUrl, siteKey)
println("CAPTCHA diselesaikan, panjang token: ${token.length}")
// Buat sesi dan buka halaman
val session = PulsarContexts.createSession()
val page = session.open(targetUrl)
val driver = session.getOrCreateBoundDriver()
// Sisipkan token ke textarea tersembunyi menggunakan properti value (aman)
driver?.evaluate("""
(function() {
var el = document.querySelector('#g-recaptcha-response');
if (el) el.value = arguments[0];
})('$token');
""")
// Kirim formulir
driver?.evaluate("document.querySelector('form').submit();")
// Tunggu navigasi
Thread.sleep(3000)
// Ekstrak data dari halaman hasil
val document = session.parse(page)
mapOf(
"title" to document.selectFirstTextOrNull("h1"),
"content" to document.selectFirstTextOrNull(".content"),
"success" to (document.body().text().contains("success", ignoreCase = true))
)
}
}
fun main() = runBlocking {
val apiKey = System.getenv("CAPSOLVER_API_KEY") ?: "kunci_api_anda"
val capSolver = CapSolverService(apiKey)
val extractor = ReCaptchaV2Extractor(capSolver)
val result = extractor.extractWithCaptcha(
targetUrl = "https://example.com/halaman-terlindungi",
siteKey = "6LcxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxABC"
)
println("Hasil ekstraksi: $result")
}
reCAPTCHA v3 dengan Browser4
kotlin
class ReCaptchaV3Extractor(
private val capSolver: CapSolverService
) {
suspend fun extractWithCaptchaV3(
targetUrl: String,
siteKey: String,
action: String = "submit"
): Map<String, Any?> {
println("Menyelesaikan reCAPTCHA v3 dengan aksi: $action")
// Selesaikan reCAPTCHA v3 dengan aksi halaman khusus
val token = capSolver.solveReCaptchaV3(
websiteUrl = targetUrl,
websiteKey = siteKey,
pageAction = action
)
println("Token diperoleh secara sukses")
// Buat sesi dan buka halaman
val session = PulsarContexts.createSession()
val page = session.open(targetUrl)
val driver = session.getOrCreateBoundDriver()
// Sisipkan token ke input tersembunyi (menggunakan penugasan nilai yang aman)
driver?.evaluate("""
(function(tokenValue) {
var input = document.querySelector('input[name="g-recaptcha-response"]');
if (input) {
input.value = tokenValue;
} else {
var hidden = document.createElement('input');
hidden.type = 'hidden';
hidden.name = 'g-recaptcha-response';
hidden.value = tokenValue;
var form = document.querySelector('form');
if (form) form.appendChild(hidden);
}
})('$token');
""")
// Klik tombol submit
driver?.evaluate("document.querySelector('#submit-btn').click();")
Thread.sleep(3000)
val document = session.parse(page)
mapOf(
"result" to document.selectFirstTextOrNull(".result-data"),
"status" to "success"
)
}
}
Cloudflare Turnstile dengan Browser4
kotlin
class TurnstileExtractor(
private val capSolver: CapSolverService
) {
suspend fun extractWithTurnstile(targetUrl: String, siteKey: String): Map<String, Any?> {
println("Menyelesaikan Cloudflare Turnstile...")
// Selesaikan dengan metadata opsional (aksi dan cdata)
val token = capSolver.solveTurnstile(
targetUrl,
siteKey,
action = "login", // opsional
cdata = "0000-1111-2222-3333-example" // opsional
)
println("Turnstile berhasil diselesaikan!")
val session = PulsarContexts.createSession()
val page = session.open(targetUrl)
val driver = session.getOrCreateBoundDriver()
// Menyuntikkan token Turnstile (menggunakan penugasan nilai yang aman)
driver?.evaluate("""
(function(tokenValue) {
var input = document.querySelector('input[name="cf-turnstile-response"]');
if (input) input.value = tokenValue;
})('$token');
""")
// Kirim
driver?.evaluate("document.querySelector('form').submit();")
Thread.sleep(3000)
val document = session.parse(page)
mapOf(
"title" to document.selectFirstTextOrNull("title"),
"content" to document.selectFirstTextOrNull("body")?.take(500)
)
}
}
---
## Integrasi dengan Browser4 X-SQL
Browser4's X-SQL menawarkan kemampuan ekstraksi yang kuat. Berikut cara menggabungkannya dengan penyelesaian CAPTCHA:
```kotlin
class XSqlCaptchaExtractor(
private val capSolver: CapSolverService
) {
suspend fun extractProductsWithCaptcha(
targetUrl: String,
siteKey: String
): List<Map<String, Any?>> {
// Selesaikan CAPTCHA terlebih dahulu
val token = capSolver.solveReCaptchaV2(targetUrl, siteKey)
// Membuat sesi dan membangun sesi yang terautentikasi
val session = PulsarContexts.createSession()
val page = session.open(targetUrl)
val driver = session.getOrCreateBoundDriver()
driver?.evaluate("""
(function(tokenValue) {
var el = document.querySelector('#g-recaptcha-response');
if (el) el.value = tokenValue;
document.querySelector('form').submit();
})('$token');
""")
Thread.sleep(3000)
// Sekarang parsing halaman dan ekstrak data produk
val document = session.parse(page)
// Ekstrak data produk menggunakan metode sesi bawaan
val products = mutableListOf<Map<String, Any?>>()
val productElements = document.select(".product-item")
for ((index, element) in productElements.withIndex()) {
if (index >= 50) break // BATAS 50
products.add(mapOf(
"name" to element.selectFirstTextOrNull(".product-name"),
"price" to element.selectFirstTextOrNull(".price")?.let {
"""(\d+\.?\d*)""".toRegex().find(it)?.groupValues?.get(1)?.toDoubleOrNull() ?: 0.0
},
"rating" to element.selectFirstTextOrNull(".rating")
))
}
return products.map { row ->
mapOf(
"name" to row["name"],
"price" to row["price"],
"rating" to row["rating"],
"image_url" to row["image_url"]
)
}
}
}
Pola Pra-Autentikasi
Untuk situs yang memerlukan CAPTCHA sebelum mengakses konten, gunakan alur kerja pra-autentikasi:
kotlin
import okhttp3.Cookie
import okhttp3.CookieJar
import okhttp3.HttpUrl
class PreAuthenticator(
private val capSolver: CapSolverService
) {
data class AuthSession(
val cookies: Map<String, String>,
val userAgent: String?
)
suspend fun authenticateWithCaptcha(
loginUrl: String,
siteKey: String
): AuthSession {
// Selesaikan CAPTCHA
val captchaToken = capSolver.solveReCaptchaV2(loginUrl, siteKey)
// Kirim CAPTCHA untuk mendapatkan cookie sesi
val client = OkHttpClient.Builder()
.cookieJar(object : CookieJar {
private val cookies = mutableListOf<Cookie>()
override fun saveFromResponse(url: HttpUrl, cookieList: List<Cookie>) {
cookies.addAll(cookieList)
}
override fun loadForRequest(url: HttpUrl): List<Cookie> = cookies
})
.build()
val formBody = okhttp3.FormBody.Builder()
.add("g-recaptcha-response", captchaToken)
.build()
val request = Request.Builder()
.url(loginUrl)
.post(formBody)
.build()
val response = client.newCall(request).execute()
// Ekstrak cookie dari respons
val responseCookies = response.headers("Set-Cookie")
.associate { cookie ->
val parts = cookie.split(";")[0].split("=", limit = 2)
parts[0] to (parts.getOrNull(1) ?: "")
}
return AuthSession(
cookies = responseCookies,
userAgent = response.request.header("User-Agent")
)
}
}
class AuthenticatedExtractor(
private val preAuth: PreAuthenticator,
private val capSolver: CapSolverService
) {
suspend fun extractWithAuth(
loginUrl: String,
targetUrl: String,
siteKey: String
): Map<String, Any?> {
// Pra-autentikasi
val authSession = preAuth.authenticateWithCaptcha(loginUrl, siteKey)
println("Sesi berhasil dibuat dengan ${authSession.cookies.size} cookie")
// Membuat sesi Browser4
val session = PulsarContexts.createSession()
// Konfigurasi sesi dengan cookie
val cookieScript = authSession.cookies.entries.joinToString(";") { (k, v) ->
"$k=$v"
}
val page = session.open(targetUrl)
val driver = session.getOrCreateBoundDriver()
// Set cookie
driver?.evaluate("document.cookie = '$cookieScript';")
// Muat ulang dengan sesi yang terautentikasi
driver?.evaluate("location.reload();")
Thread.sleep(2000)
// Ekstrak data
val document = session.parse(page)
return mapOf(
"authenticated" to true,
"content" to document.selectFirstTextOrNull(".protected-content"),
"userData" to document.selectFirstTextOrNull(".user-profile")
)
}
}
Integrasi OpenRouter untuk Ekstraksi Berbasis LLM
Kemampuan AI Browser4 dapat ditingkatkan dengan OpenRouter, gateway API yang terpadu untuk mengakses berbagai model LLM. Ini memungkinkan ekstraksi konten yang cerdas yang menyesuaikan diri dengan struktur halaman yang berbeda.
Layanan OpenRouter
kotlin
import com.google.gson.Gson
import com.google.gson.JsonObject
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.RequestBody.Companion.toRequestBody
import java.util.concurrent.TimeUnit
data class ChatMessage(val role: String, val content: String)
data class ChatCompletion(val content: String, val model: String, val usage: TokenUsage)
data class TokenUsage(val promptTokens: Int, val completionTokens: Int, val totalTokens: Int)
class OpenRouterService(private val apiKey: String) {
private val client = OkHttpClient.Builder()
.connectTimeout(60, TimeUnit.SECONDS)
.readTimeout(60, TimeUnit.SECONDS)
.build()
private val gson = Gson()
private val baseUrl = "https://openrouter.ai/api/v1"
private val jsonMediaType = "application/json".toMediaType()
fun chat(
messages: List<ChatMessage>,
model: String = "openai/gpt-4o-mini"
): ChatCompletion {
val payload = mapOf(
"model" to model,
"messages" to messages.map { mapOf("role" to it.role, "content" to it.content) }
)
val request = Request.Builder()
.url("$baseUrl/chat/completions")
.header("Authorization", "Bearer $apiKey")
.post(gson.toJson(payload).toRequestBody(jsonMediaType))
.build()
val response = client.newCall(request).execute()
val result = gson.fromJson(response.body?.string(), JsonObject::class.java)
val choice = result.getAsJsonArray("choices")?.get(0)?.asJsonObject
val content = choice?.getAsJsonObject("message")?.get("content")?.asString ?: ""
val usage = result.getAsJsonObject("usage")
return ChatCompletion(
content = content,
model = result.get("model")?.asString ?: model,
usage = TokenUsage(
promptTokens = usage?.get("prompt_tokens")?.asInt ?: 0,
completionTokens = usage?.get("completion_tokens")?.asInt ?: 0,
totalTokens = usage?.get("total_tokens")?.asInt ?: 0
)
)
}
fun extractStructuredData(html: String, schema: String): String {
val prompt = """
Ekstrak data berikut dari konten HTML ini.
Kembalikan HANYA JSON yang valid sesuai skema ini: $schema
HTML:
${html.take(4000)}
""".trimIndent()
return chat(listOf(ChatMessage("user", prompt))).content
}
fun listModels(): List<String> {
val request = Request.Builder()
.url("$baseUrl/models")
.header("Authorization", "Bearer $apiKey")
.build()
val response = client.newCall(request).execute()
val result = gson.fromJson(response.body?.string(), JsonObject::class.java)
return result.getAsJsonArray("data")?.mapNotNull {
it.asJsonObject.get("id")?.asString
} ?: emptyList()
}
}
Ekstraksi Berbasis LLM dengan Penyelesaian CAPTCHA
Gabungkan penyelesaian CAPTCHA dengan ekstraksi konten yang cerdas:
kotlin
class SmartExtractor(
private val capSolver: CapSolverService,
private val openRouter: OpenRouterService
) {
suspend fun extractWithAI(
targetUrl: String,
siteKey: String?,
extractionPrompt: String
): Map<String, Any?> {
// Langkah 1: Selesaikan CAPTCHA jika diperlukan
val captchaToken = siteKey?.let {
println("Menyelesaikan CAPTCHA...")
capSolver.solveReCaptchaV2(targetUrl, it)
}
// Langkah 2: Membuat sesi dan membuka halaman
val session = PulsarContexts.createSession()
val page = session.open(targetUrl)
val driver = session.getOrCreateBoundDriver()
captchaToken?.let { token ->
driver?.evaluate("""
(function(tokenValue) {
var el = document.querySelector('#g-recaptcha-response');
if (el) el.value = tokenValue;
var form = document.querySelector('form');
if (form) form.submit();
})('$token');
""")
Thread.sleep(3000)
}
// Langkah 3: Ekstrak konten halaman
val document = session.parse(page)
val pageContent = document.body().text().take(8000)
// Langkah 4: Gunakan LLM untuk ekstraksi data terstruktur
val llmResponse = openRouter.chat(listOf(
ChatMessage("system", "Anda adalah asisten ekstraksi data. Ekstrak data terstruktur dari halaman web."),
ChatMessage("user", """
$extractionPrompt
Konten halaman:
$pageContent
""".trimIndent())
))
println("LLM menggunakan ${llmResponse.usage.totalTokens} token")
return mapOf(
"url" to targetUrl,
"captchaSolved" to (captchaToken != null),
"extractedData" to llmResponse.content,
"tokensUsed" to llmResponse.usage.totalTokens
)
}
}
// Penggunaan
fun main() = runBlocking {
val capSolver = CapSolverService(System.getenv("CAPSOLVER_API_KEY")!!)
val openRouter = OpenRouterService(System.getenv("OPENROUTER_API_KEY")!!)
val extractor = SmartExtractor(capSolver, openRouter)
val result = extractor.extractWithAI(
targetUrl = "https://example.com/products",
siteKey = "6LcxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxABC",
extractionPrompt = """
Ekstrak semua produk dengan:
- nama
- harga (sebagai angka)
- ketersediaan (in_stock/out_of_stock)
- rating (1-5)
Kembalikan sebagai array JSON.
""".trimIndent()
)
println("Hasil ekstraksi: ${result["extractedData"]}")
}
Pembuatan Selektor Adaptif
Gunakan LLM untuk menghasilkan selektor CSS untuk struktur halaman yang tidak dikenal:
kotlin
class AdaptiveExtractor(
private val capSolver: CapSolverService,
private val openRouter: OpenRouterService
) {
suspend fun extractWithAdaptiveSelectors(
targetUrl: String,
siteKey: String?,
dataFields: List<String>
): Map<String, Any?> {
// Selesaikan CAPTCHA terlebih dahulu
val token = siteKey?.let { capSolver.solveReCaptchaV2(targetUrl, it) }
val session = PulsarContexts.createSession()
val page = session.open(targetUrl)
val driver = session.getOrCreateBoundDriver()
token?.let { t ->
driver?.evaluate("""
(function(tokenValue) {
var el = document.querySelector('#g-recaptcha-response');
if (el) el.value = tokenValue;
})('$t');
""")
}
// Dapatkan struktur HTML halaman
val htmlSample = driver?.evaluate("document.body.innerHTML")?.toString()?.take(5000) ?: ""
// Minta LLM untuk menghasilkan selektor
val selectorPrompt = """
Analisis HTML ini dan berikan selektor CSS untuk bidang berikut: ${dataFields.joinToString(", ")}
Contoh HTML:
$htmlSample
Kembalikan JSON seperti: {"fieldName": "css-selector", ...}
""".trimIndent()
val selectorsJson = openRouter.chat(listOf(ChatMessage("user", selectorPrompt))).content
val selectors = Gson().fromJson(selectorsJson, Map::class.java) as Map<String, String>
// Ekstrak menggunakan selektor yang dihasilkan
val document = session.parse(page)
val extractedData = selectors.mapValues { (_, selector) ->
document.selectFirstTextOrNull(selector)
}
return mapOf(
"url" to targetUrl,
"selectors" to selectors,
"data" to extractedData
)
}
}
Ekstraksi Paralel dengan Korelasi
Desain Browser4 yang selaras dengan korelasi memungkinkan penyelesaian CAPTCHA yang efisien secara paralel:
kotlin
import kotlinx.coroutines.*
import kotlinx.coroutines.channels.Channel
data class ExtractionJob(
val url: String,
val siteKey: String?
)
data class ExtractionResult(
val url: String,
val data: Map<String, Any?>?,
val captchaSolved: Boolean,
val error: String?,
val duration: Long
)
class ParallelExtractor(
private val capSolver: CapSolverService,
private val concurrency: Int = 5
) {
suspend fun extractAll(jobs: List<ExtractionJob>): List<ExtractionResult> = coroutineScope {
val channel = Channel<ExtractionJob>(Channel.UNLIMITED)
val results = mutableListOf<ExtractionResult>()
// Kirim semua pekerjaan ke channel
jobs.forEach { channel.send(it) }
channel.close()
// Proses dengan konkurensi terbatas
val workers = (1..concurrency).map { workerId ->
async {
val workerResults = mutableListOf<ExtractionResult>()
// Setiap pekerja membuat sesi sendiri untuk keamanan thread
val workerSession = PulsarContexts.createSession()
for (job in channel) {
val startTime = System.currentTimeMillis()
var captchaSolved = false
try {
// Selesaikan CAPTCHA jika kunci situs diberikan
val token = job.siteKey?.let {
captchaSolved = true
capSolver.solveReCaptchaV2(job.url, it)
}
// Ekstrak data
val page = workerSession.open(job.url)
token?.let { t ->
val driver = workerSession.getOrCreateBoundDriver()
driver?.evaluate("""
(function(tokenValue) {
var el = document.querySelector('#g-recaptcha-response');
if (el) el.value = tokenValue;
})('$t');
""")
}
val document = workerSession.parse(page)
workerResults.add(ExtractionResult(
url = job.url,
data = mapOf(
"title" to document.selectFirstTextOrNull("title"),
"h1" to document.selectFirstTextOrNull("h1")
),
captchaSolved = captchaSolved,
error = null,
duration = System.currentTimeMillis() - startTime
))
} catch (e: Exception) {
workerResults.add(ExtractionResult(
url = job.url,
data = null,
captchaSolved = captchaSolved,
error = e.message,
duration = System.currentTimeMillis() - startTime
))
}
}
workerResults
}
}
workers.awaitAll().flatten()
}
}
// Penggunaan
fun main() = runBlocking {
val capSolver = CapSolverService(System.getenv("CAPSOLVER_API_KEY")!!)
val extractor = ParallelExtractor(capSolver, concurrency = 5)
val jobs = listOf(
ExtractionJob("https://site1.com/data", "6Lc..."),
ExtractionJob("https://site2.com/data", null),
ExtractionJob("https://site3.com/data", "6Lc..."),
)
val results = extractor.extractAll(jobs)
val solved = results.count { it.captchaSolved }
println("Selesai ${results.size} ekstraksi, selesaikan $solved CAPTCHA")
results.forEach { r ->
println("${r.url}: ${r.duration}ms - ${r.error ?: "berhasil"}")
}
}
Praktik Terbaik
1. Penanganan Kesalahan dengan Pengulangan
kotlin
suspend fun <T> withRetry(
maxRetries: Int = 3,
initialDelay: Long = 1000,
block: suspend () -> T
): T {
var lastException: Exception? = null
repeat(maxRetries) { attempt ->
try {
return block()
} catch (e: Exception) {
lastException = e
println("Percobaan ${attempt + 1} gagal: ${e.message}")
delay(initialDelay * (attempt + 1))
}
}
throw lastException ?: Exception("Jumlah pengulangan maksimum tercapai")
}
// Penggunaan
val token = withRetry(maxRetries = 3) {
capSolver.solveReCaptchaV2(url, siteKey)
}
2. Manajemen Saldo
kotlin
suspend fun ensureSufficientBalance(
capSolver: CapSolverService,
minBalance: Double = 1.0
) {
val balance = capSolver.checkBalance()
if (balance < minBalance) {
throw Exception("Saldo CapSolver tidak cukup: $${"%.2f".format(balance)}. Silakan isi ulang.")
}
println("Saldo CapSolver: $${"%.2f".format(balance)}")
}
3. Cache Token
kotlin
class TokenCache(private val ttlMs: Long = 90_000) {
private data class CachedToken(val token: String, val timestamp: Long)
private val cache = mutableMapOf<String, CachedToken>()
private fun getKey(domain: String, siteKey: String) = "$domain:$siteKey"
fun get(domain: String, siteKey: String): String? {
val key = getKey(domain, siteKey)
val cached = cache[key] ?: return null
if (System.currentTimeMillis() - cached.timestamp > ttlMs) {
cache.remove(key)
return null
}
return cached.token
}
fun set(domain: String, siteKey: String, token: String) {
val key = getKey(domain, siteKey)
cache[key] = CachedToken(token, System.currentTimeMillis())
}
}
// Penggunaan dengan cache
class CachedCapSolver(
private val capSolver: CapSolverService,
private val cache: TokenCache = TokenCache()
) {
suspend fun solveReCaptchaV2Cached(websiteUrl: String, websiteKey: String): String {
val domain = java.net.URL(websiteUrl).host
cache.get(domain, websiteKey)?.let {
println("Menggunakan token yang dicache")
return it
}
val token = capSolver.solveReCaptchaV2(websiteUrl, websiteKey)
cache.set(domain, websiteKey, token)
return token
}
}
Opsi Konfigurasi
| Pengaturan | Deskripsi | Nilai Default |
|---|---|---|
CAPSOLVER_API_KEY |
Kunci API CapSolver Anda | - |
OPENROUTER_API_KEY |
Kunci API OpenRouter untuk fitur LLM | - |
PROXY_ROTATION_URL |
URL layanan rotasi proxy | - |
Browser4 menggunakan application.properties untuk konfigurasi tambahan |
Kesimpulan
Mengintegrasikan CapSolver dengan Browser4 menciptakan kombinasi yang kuat untuk ekstraksi data web berkecepatan tinggi. Arsitektur Browser4 yang aman korutin dan kemampuan kinerja ekstremnya, dikombinasikan dengan penyelesaian CAPTCHA yang andal dari CapSolver, memungkinkan ekstraksi data dalam skala besar.
Pola integrasi kunci:
- Injeksi Token Langsung: Sisipkan token yang diselesaikan melalui evaluasi JavaScript
- Pengotentikan Awal: Selesaikan CAPTCHA untuk membangun sesi sebelum ekstraksi
- Pemrosesan Paralel: Manfaatkan korutin untuk penyelesaian CAPTCHA yang bersamaan
- Integrasi X-SQL: Gabungkan penyelesaian CAPTCHA dengan bahasa query Browser4 yang kuat
Baik Anda membangun sistem pemantauan harga, alur pipa penelitian pasar, atau platform agregasi data, kombinasi Browser4 + CapSolver menyediakan keandalan dan skalabilitas yang diperlukan untuk lingkungan produksi.
Siap memulai? Daftar ke CapSolver dan gunakan kode bonus BROWSER4 untuk bonus tambahan 6% pada recharge pertama Anda!
FAQ
Apa itu Browser4?
Browser4 adalah kerangka kerja otomasi browser berkinerja tinggi dari PulsarRPA yang aman korutin. Dibangun dalam Kotlin dan dirancang untuk ekstraksi data berbasis AI, mendukung 100.000-200.000 kunjungan halaman kompleks per hari per mesin.
Bagaimana CapSolver terintegrasi dengan Browser4?
CapSolver terintegrasi dengan Browser4 melalui kelas layanan yang menyelesaikan CAPTCHA via API CapSolver. Token yang diselesaikan kemudian disisipkan ke halaman menggunakan kemampuan evaluasi JavaScript Browser4 (driver.evaluate()).
Jenis CAPTCHA apa yang bisa diselesaikan CapSolver?
CapSolver mendukung reCAPTCHA v2, reCAPTCHA v3, Cloudflare Turnstile, Cloudflare Challenge (5 detik), AWS WAF, GeeTest v3/v4, dan banyak lagi.
Berapa biaya CapSolver?
CapSolver menawarkan harga kompetitif berdasarkan jenis dan volume CAPTCHA yang diselesaikan. Kunjungi capsolver.com untuk harga terkini. Gunakan kode BROWSER4 untuk bonus 6%.
Bahasa pemrograman apa yang digunakan Browser4?
Browser4 dibangun dalam Kotlin dan berjalan di JVM (Java 17+). Browser4 juga bisa digunakan dari aplikasi Java.
Apakah Browser4 bisa menangani penyelesaian CAPTCHA paralel?
Ya! Desain Browser4 yang aman korutin memungkinkan pemrosesan paralel yang efisien. Dengan API CapSolver, Anda bisa menyelesaikan beberapa CAPTCHA secara bersamaan di berbagai pekerjaan ekstraksi.
Bagaimana cara saya menemukan kunci CAPTCHA situs?
Kunci situs biasanya ditemukan dalam sumber HTML halaman:
- reCAPTCHA: atribut
data-sitekeypada elemen.g-recaptcha - Turnstile: atribut
data-sitekeypada elemen.cf-turnstile - Atau periksa permintaan jaringan untuk kunci dalam panggilan API
Pernyataan Kepatuhan: Informasi yang diberikan di blog ini hanya untuk tujuan informasi. CapSolver berkomitmen untuk mematuhi semua hukum dan peraturan yang berlaku. Penggunaan jaringan CapSolver untuk kegiatan ilegal, penipuan, atau penyalahgunaan sangat dilarang dan akan diselidiki. Solusi penyelesaian captcha kami meningkatkan pengalaman pengguna sambil memastikan kepatuhan 100% dalam membantu menyelesaikan kesulitan captcha selama pengambilan data publik. Kami mendorong penggunaan layanan kami secara bertanggung jawab. Untuk informasi lebih lanjut, silakan kunjungi Syarat Layanan dan Kebijakan Privasi.
Lebih lanjut

Cara Menyelesaikan Captcha di Maxun dengan Integrasi CapSolver
Panduan praktis untuk mengintegrasikan CapSolver dengan Maxun dalam penggunaan nyata pengambilan data web. Pelajari cara mengelola reCAPTCHA, Cloudflare Turnstile, dan situs yang dilindungi CAPTCHA dengan menggunakan alur kerja pre-auth dan robot.

Adélia Cruz
21-Jan-2026

Cara menyelesaikan Captcha di Browser4 dengan integrasi CapSolver
Otomasi Browser4 dengan throughput tinggi dikombinasikan dengan CapSolver untuk menangani tantangan CAPTCHA dalam ekstraksi data web skala besar.

Anh Tuan
21-Jan-2026

Apa itu Bot Scraping dan Bagaimana Cara Membuatnya
Pelajari apa itu bot scraping dan cara membuatnya untuk ekstraksi data otomatis. Jelajahi alat terbaik, teknik navigasi keamanan, dan praktik scraping yang etis.

Emma Foster
16-Jan-2026

Scrapy vs. Selenium: Mana yang Terbaik untuk Proyek Scraping Web Anda?
Temukan kekuatan dan perbedaan antara Scrapy dan Selenium untuk pengambilan data web. Pelajari alat mana yang paling sesuai dengan proyek Anda dan cara mengatasi tantangan seperti CAPTCHA.

Emma Foster
14-Jan-2026

Cara Menggunakan Selenium Driverless untuk Pengambilan Data Web yang Efisien
Pelajari cara menggunakan Selenium Driverless untuk pengambilan data web yang efisien. Panduan ini memberikan instruksi langkah demi langkah tentang menyiapkan lingkungan Anda, menulis skrip Selenium Driverless pertama Anda, dan menangani konten dinamis. Mempermudah tugas pengambilan data web Anda dengan menghindari kompleksitas manajemen WebDriver tradisional, sehingga membuat proses ekstraksi data Anda lebih sederhana, lebih cepat, dan lebih portabel.

Aloísio Vítor
14-Jan-2026

Cara Menyelesaikan Captcha di Agno dengan Integrasi CapSolver
Pelajari cara mengintegrasikan CapSolver dengan Agno untuk menyelesaikan tantangan reCAPTCHA v2/v3, Cloudflare Turnstile, dan WAF dalam agen AI otonom. Termasuk contoh Python nyata untuk pengambilan data web dan otomatisasi.

Emma Foster
13-Jan-2026


