Cara Memecahkan CAPTCHA di Browser Use dengan Alat Kustom

browser use captcha - How to Solve CAPTCHAs in Browser Use With a Custom Tool

Untuk memecahkan CAPTCHA di Browser Use pada browser Anda sendiri, daftarkan alat kustom yang membaca sitekey widget dari halaman, meminta token ke CapSkip, lalu menuliskannya ke formulir, kemudian beri tahu agen melalui pesan sistemnya bahwa alat itu ada. Itu sudah mencakup penanganan CAPTCHA Browser Use di Chromium lokal, kecuali dua batas waktu yang sama-sama bernilai default 180 detik dan perlu dinaikkan, karena pemecahan reCAPTCHA bisa berlangsung lebih lama dari keduanya. Bagian pesan sistem ini tidak opsional. Prompt sistem default Browser Use memberi tahu model bahwa CAPTCHA dipecahkan secara otomatis, yang benar di browser cloud Browser Use tetapi salah di Chromium lokal, sehingga tanpa pesan itu agen akan menunggu pemecahan yang tidak pernah datang. Panduan ini membangun alat CAPTCHA untuk Browser Use langkah demi langkah, diperiksa terhadap Browser Use 0.13.10.

Apa yang Anda butuhkan

  • CapSkip yang berjalan di komputer Windows. Alat di bawah ini menangani reCAPTCHA v2, termasuk widget invisible dan Enterprise, serta widget Cloudflare Turnstile.
  • Python 3.11 atau lebih baru, yang diwajibkan Browser Use, dengan browser-use dan paket capskip versi 1.3.0 atau lebih baru. Browser Use mengendalikan Chrome atau Chromium yang ditemukannya di mesin tersebut.
  • API key untuk model chat apa pun yang Anda berikan ke agen; untuk Claude, setel sebagai ANTHROPIC_API_KEY. Contoh kodenya memakai Claude Opus 5.5 melalui ChatAnthropic dengan adaptive thinking diaktifkan, dan argumen itu penting: tanpanya, Browser Use 0.13.10 memaksakan tool choice model, yang ditolak oleh Claude Opus 5.5 dan Sonnet 5.5, sehingga setiap langkah gagal.
  • Sebuah alamat untuk pemecah CAPTCHA. Dalam mode Local, CapSkip menjawab di 127.0.0.1 hanya untuk perangkat itu; dalam mode Server, CapSkip mendengarkan di alamat jaringan atau IP publik Anda, sehingga agen di mesin lain dapat memanggilnya melalui API. Keduanya dikonfigurasi di pengaturan koneksi.
# Quoted, so cmd.exe does not read >= as a redirect
pip install browser-use "capskip>=1.3.0"

Mengapa Browser Use mengabaikan CAPTCHA di browser lokal?

Karena memang diperintahkan begitu. Aturan browser di prompt sistem yang dipakai Browser Use dengan pengaturan default-nya memuat baris "CAPTCHAs are automatically solved by the browser" (CAPTCHA dipecahkan secara otomatis oleh browser), diikuti instruksi agar tidak mencoba memecahkannya secara manual. Itu menggambarkan browser cloud Browser Use, yang memecahkan CAPTCHA di proxy mereka sendiri dan memberitahukannya ke library. Library ini punya watchdog yang sesuai, diaktifkan oleh pengaturan captcha_solver pada BrowserProfile (aktif secara default), yang menjeda agen selagi browser cloud memecahkan CAPTCHA. Watchdog itu hanya mendengarkan event yang dikirim browser cloud tersebut.

Di Chromium pada mesin Anda sendiri, event seperti itu tidak pernah datang. Agen melihat widget, memercayai aturan tersebut, lalu menunggu, menggulir, atau mencoba jalur lain sampai kehabisan langkah. Ketika eksekusi agen berakhir seperti itu, Browser Use menyarankan untuk beralih ke browser cloud miliknya. Alternatifnya, jika Anda ingin browser tetap berada di perangkat keras Anda sendiri, adalah memberi agen sebuah alat yang benar-benar memecahkan widget dan mengoreksi aturan yang diberikan kepadanya.

Langkah 1: daftarkan alat solve_captcha

Alat kustom adalah fungsi async yang didaftarkan dengan decorator tools.action pada instance Tools. Browser Use menyuntikkan parameter khusus berdasarkan namanya: browser_session memberi Anda sesi yang sedang aktif dan page_url memberi alamat halaman saat ini. Alat ini membutuhkan dua potongan kecil JavaScript, satu untuk menemukan widget dan satu untuk mengisi token.

FIND = """() => {
  const w = document.querySelector(
    '.g-recaptcha[data-sitekey], .cf-turnstile[data-sitekey]');
  if (!w) return null;
  return {
    kind: w.classList.contains('cf-turnstile') ? 'turnstile' : 'recaptcha',
    sitekey: w.dataset.sitekey,
    invisible: w.dataset.size === 'invisible' || w.tagName !== 'DIV',
    enterprise: !!document.querySelector(
      'script[src*="recaptcha/enterprise.js"]'),
    callback: w.dataset.callback || null,
  };
}"""

FILL = """(kind, token, callback) => {
  const name = kind === 'turnstile' ? 'cf-turnstile-response'
                                    : 'g-recaptcha-response';
  const fields = document.querySelectorAll(`[name="${name}"]`);
  fields.forEach(f => { f.value = token; });
  if (callback && typeof window[callback] === 'function') {
    window[callback](token);
  }
  return fields.length;
}"""

Keduanya ditulis sebagai arrow function, karena metode evaluate milik objek page menolak bentuk lain. Metode itu mengoper argumen tambahan sebagai JSON, dan selalu mengembalikan string: objek kembali dalam bentuk JSON, angka sebagai digitnya, dan null sebagai string kosong. FILL menulis token ke field respons yang dibuat widget dan memanggil fungsi yang disebut di data-callback jika widget mendeklarasikannya, karena sebagian formulir menunggu callback itu alih-alih membaca field-nya.

FIND juga membaca dua hal yang diperlukan untuk pemecahan. Widget yang terikat pada tombol bersifat invisible meskipun tanpa atribut data-size, jadi elemen g-recaptcha apa pun yang bukan div dihitung sebagai invisible. Dan halaman yang memuat skrip enterprise.js milik Google dipecahkan sebagai reCAPTCHA Enterprise, karena widget Enterprise memakai markup yang sama dengan widget standar.

@tools.action(
    "Solve the reCAPTCHA v2 or Cloudflare Turnstile widget on the current "
    "page. Call it after the other fields are filled, then submit the form "
    "unless the page has already moved on."
)
async def solve_captcha(browser_session: BrowserSession, page_url: str):
    page = await browser_session.must_get_current_page()
    raw = await page.evaluate(FIND)
    widget = json.loads(raw) if raw else None
    if not widget:
        return ActionResult(error="No reCAPTCHA or Turnstile widget found.")

    try:
        if widget["kind"] == "turnstile":
            result = await solver.turnstile(widget["sitekey"], page_url)
        else:
            extra = {"invisible": 1} if widget["invisible"] else {}
            result = await solver.recaptcha(
                widget["sitekey"], page_url,
                enterprise=int(widget["enterprise"]), **extra)
    except CapSkipError as exc:
        return ActionResult(error=f"CapSkip did not solve it: {exc!r}")

    filled = await page.evaluate(
        FILL, widget["kind"], result["code"], widget["callback"])
    if filled == "0":
        return ActionResult(error="Solved, but no response field to fill.")
    return ActionResult(
        extracted_content=f"Solved the {widget['kind']} CAPTCHA on {page_url} "
                          "and filled in the token. Submit the form now, "
                          "unless the page has already moved on.",
    )

String deskripsi adalah apa yang dibaca model saat memutuskan aksi mana yang akan diambil, jadi string itu menyebutkan kapan alat harus dipanggil sekaligus apa yang dilakukannya. Pesan sukses hanya ditaruh di extracted_content. Ketika sebuah ActionResult juga menyetel long_term_memory, Browser Use menampilkan memory itu ke model dan membuang content-nya, sehingga instruksi seperti "Submit the form now" yang ditaruh di content tidak pernah sampai. Setiap kegagalan dikembalikan sebagai ActionResult dengan error yang bisa dibaca dan ditanggapi model, bukan sebagai exception.

Gunakan AsyncCapSkip di sini, bukan klien CapSkip yang sinkron. Browser Use menjalankan koneksi browser di event loop yang sama dengan alat Anda, dan pemecahan yang memblokir akan membekukan semuanya selama pemecahan berlangsung. Di Python, AsyncCapSkip adalah klien asyncio sungguhan, bukan sekadar alias.

Langkah 2: beri tahu agen bahwa alat itu ada

Berikan tools ke agen dan tambahkan satu paragraf ke pesan sistemnya. extend_system_message ditambahkan setelah prompt default, jadi paragraf itu muncul setelah aturan yang harus dikoreksinya.

EXTRA = (
    "This browser does not solve CAPTCHAs on its own, whatever the rules "
    "above say. When a page shows a reCAPTCHA or Turnstile widget, fill in "
    "the other fields, call solve_captcha, then submit the form unless the "
    "page has already moved on. Never click the CAPTCHA checkbox or "
    "challenge yourself."
)

agent = Agent(
    task="Sign up at https://example.com/signup with YOUR_EMAIL.",
    llm=ChatAnthropic(model="claude-opus-5-5", thinking={"type": "adaptive"}),
    tools=tools,
    extend_system_message=EXTRA,
    step_timeout=420,
)

Urutan dalam paragraf itu penting. Token reCAPTCHA hanya berlaku sekitar dua menit, dan panduan kedaluwarsa token reCAPTCHA menjelaskan hal itu, sementara setiap langkah model memakan waktu beberapa detik. Memecahkan CAPTCHA lebih dulu lalu mengisi formulir yang panjang bisa membuat token kedaluwarsa sebelum pengiriman, jadi agen diperintahkan untuk memecahkannya paling akhir. Model bisa melakukan ketiganya dalam satu langkah, yaitu mengetik, memecahkan, dan mengklik tombol kirim, dan Browser Use menjalankan aksi dalam satu langkah secara berurutan. Klausa tentang halaman yang sudah berpindah ditujukan untuk widget invisible. Callback widget semacam itu biasanya mengirim formulir dengan sendirinya, jadi saat FILL memanggilnya, halaman sudah berpindah, dan klik kedua hanya akan gagal.

Argumen thinking pada ChatAnthropic bukan sekadar hiasan. Browser Use meminta aksi berikutnya dari Claude melalui tool call, dan di versi 0.13.10, tanpa thinking, Browser Use memaksakan tool choice tersebut. Claude Opus 5.5 dan Sonnet 5.5 menolak tool choice yang dipaksakan dengan error 400, sehingga agen akan gagal di setiap langkah. Dengan adaptive thinking aktif, Browser Use membiarkan model memilih alatnya sendiri, dan permintaannya berhasil diproses.

Langkah 3: naikkan dua batas waktu 180 detik

Pemecahan CAPTCHA di Browser Use harus muat di dalam dua batas waktu yang terpisah, dan keduanya bernilai default 180 detik.

  • Batas per aksi. Setiap aksi dibungkus dalam timeout yang dibaca dari variabel lingkungan BROWSER_USE_ACTION_TIMEOUT_S, dan agen tidak pernah memberikan nilainya sendiri. Nilai itu dibaca sekali, saat Browser Use pertama kali memuat modul tools-nya, yang terjadi pada setiap import Agent atau Tools, jadi menyetelnya setelah itu tidak berpengaruh.
  • Timeout langkah. Parameter step_timeout pada Agent mencakup satu langkah penuh: menyiapkan state halaman, pemanggilan model, yang oleh Browser Use sendiri diberi waktu hingga 90 detik tergantung modelnya, dan setiap aksi dalam langkah itu.

Di sisi lain, SDK melakukan polling untuk reCAPTCHA hingga 300 detik (recaptchaTimeout), dan pengaturan reCAPTCHA milik CapSkip sendiri memberi sebuah tugas waktu hingga 250 detik untuk menunggu thread dan 250 detik lagi untuk memecahkannya. Sebagian besar pemecahan selesai jauh lebih cepat, tetapi antrean atau proxy yang lambat bisa membuat satu pemecahan melewati 180 detik. Dengan kedua batas pada nilai default-nya, timeout langkah terpicu lebih dulu, karena langkah dimulai sebelum aksi, dan agen melaporkan bahwa langkah itu timeout setelah 180 detik. Jika hanya step_timeout yang dinaikkan, batas per aksi yang mengambil alih: batas itu membatalkan pemecahan di tengah polling dan melaporkan bahwa browser mungkin tidak responsif, dengan menyebut CDP WebSocket yang mati. Pesan itu menyesatkan di sini. Browser-nya baik-baik saja; pemecahannya hanya berlangsung lebih lama dari batas itu. Setel kedua batas di atas batas milik SDK.

import os

# Before anything imports Agent or Tools from browser_use.
os.environ.setdefault("BROWSER_USE_ACTION_TIMEOUT_S", "330")

from browser_use import Agent  # noqa: E402

# Up to 300 s of SDK polling (a few more for the last poll), one
# model call (90 s for Claude) and the page state, with room to spare.
agent = Agent(task="...", llm=llm, tools=tools,
              extend_system_message=EXTRA, step_timeout=420)

Langkah yang timeout juga dihitung sebagai salah satu kegagalan beruntun agen, dan lima kegagalan berturut-turut menghentikan agen, jadi batas yang terlalu ketat merugikan lebih dari sekadar satu percobaan ulang.

Menjalankan CapSkip di server

Alat ini berjalan di proses Python Anda, berdampingan dengan agen. Yang penting adalah di mana proses itu berjalan, bukan di mana browser berada: bahkan ketika cdp_url milik sesi menunjuk ke Chrome di mesin lain, pemecahan tetap berjalan dari skrip Anda ke CapSkip. Selama skrip dan CapSkip berada di PC Windows yang sama, 127.0.0.1 sudah benar. Ketika agen pindah ke VPS, runner CI, atau job terjadwal di mesin lain, loopback menunjuk ke mesin yang salah dan alat ini mengembalikan NetworkException sebagai error-nya. Alihkan CapSkip ke mode Server dan ia akan mendengarkan di alamat jaringan atau IP publik Anda, sehingga agen dapat memanggilnya melalui API yang sama. Gunakan IP publik statis jika rutenya melewati internet, aktifkan validasi API key, dan batasi port dengan aturan Windows Firewall. Pemecah CAPTCHA tetap berada di mesin Windows milik Anda sendiri, dan pemecahan tetap tanpa kuota, berapa pun CAPTCHA yang ditemui agen.

SDK tidak membaca variabel lingkungan dengan sendirinya. Baca CAPSKIP_HOST, CAPSKIP_PORT dan CAPSKIP_API_KEY di kode Anda lalu berikan ke AsyncCapSkip, seperti pada contoh lengkap.

Contoh lengkap yang berfungsi

# pip install browser-use "capskip>=1.3.0"
import asyncio
import json
import os

# Browser Use reads this once, when its tools load, so set it first.
os.environ.setdefault("BROWSER_USE_ACTION_TIMEOUT_S", "330")

from browser_use import ActionResult, Agent, BrowserSession, ChatAnthropic, Tools
from capskip import AsyncCapSkip, CapSkipError

solver = AsyncCapSkip(
    apiKey=os.getenv("CAPSKIP_API_KEY", "capskip"),
    host=os.getenv("CAPSKIP_HOST", "127.0.0.1"),
    port=int(os.getenv("CAPSKIP_PORT", "8080")),
)
tools = Tools()

FIND = """() => {
  const w = document.querySelector(
    '.g-recaptcha[data-sitekey], .cf-turnstile[data-sitekey]');
  if (!w) return null;
  return {
    kind: w.classList.contains('cf-turnstile') ? 'turnstile' : 'recaptcha',
    sitekey: w.dataset.sitekey,
    invisible: w.dataset.size === 'invisible' || w.tagName !== 'DIV',
    enterprise: !!document.querySelector(
      'script[src*="recaptcha/enterprise.js"]'),
    callback: w.dataset.callback || null,
  };
}"""

FILL = """(kind, token, callback) => {
  const name = kind === 'turnstile' ? 'cf-turnstile-response'
                                    : 'g-recaptcha-response';
  const fields = document.querySelectorAll(`[name="${name}"]`);
  fields.forEach(f => { f.value = token; });
  if (callback && typeof window[callback] === 'function') {
    window[callback](token);
  }
  return fields.length;
}"""


@tools.action(
    "Solve the reCAPTCHA v2 or Cloudflare Turnstile widget on the current "
    "page. Call it after the other fields are filled, then submit the form "
    "unless the page has already moved on."
)
async def solve_captcha(browser_session: BrowserSession, page_url: str):
    page = await browser_session.must_get_current_page()
    raw = await page.evaluate(FIND)
    widget = json.loads(raw) if raw else None
    if not widget:
        return ActionResult(error="No reCAPTCHA or Turnstile widget found.")
    try:
        if widget["kind"] == "turnstile":
            result = await solver.turnstile(widget["sitekey"], page_url)
        else:
            extra = {"invisible": 1} if widget["invisible"] else {}
            result = await solver.recaptcha(
                widget["sitekey"], page_url,
                enterprise=int(widget["enterprise"]), **extra)
    except CapSkipError as exc:
        return ActionResult(error=f"CapSkip did not solve it: {exc!r}")
    filled = await page.evaluate(
        FILL, widget["kind"], result["code"], widget["callback"])
    if filled == "0":
        return ActionResult(error="Solved, but no response field to fill.")
    return ActionResult(
        extracted_content=f"Solved the {widget['kind']} CAPTCHA on {page_url} "
                          "and filled in the token. Submit the form now, "
                          "unless the page has already moved on.",
    )


EXTRA = (
    "This browser does not solve CAPTCHAs on its own, whatever the rules "
    "above say. When a page shows a reCAPTCHA or Turnstile widget, fill in "
    "the other fields, call solve_captcha, then submit the form unless the "
    "page has already moved on. Never click the CAPTCHA checkbox or "
    "challenge yourself."
)


async def main():
    agent = Agent(
        task="Sign up at https://example.com/signup with YOUR_EMAIL, "
             "then report what the page says.",
        # Adaptive thinking lets Browser Use leave the tool choice to Claude.
        llm=ChatAnthropic(model="claude-opus-5-5", thinking={"type": "adaptive"}),
        tools=tools,
        extend_system_message=EXTRA,
        step_timeout=420,
    )
    history = await agent.run(max_steps=25)
    print(history.final_result())


asyncio.run(main())

Kami menjalankan loop ini dari awal sampai akhir terhadap halaman uji untuk widget checkbox, widget invisible yang terikat pada tombol, halaman Enterprise, dan widget Turnstile, dengan pengganti model berbasis skrip agar setiap langkah bisa diprediksi. Prompt tiba dengan paragraf tambahan setelah aturan default, solve_captcha muncul di antara aksi yang bisa dipilih model, token masuk ke formulir, fungsi data-callback terpicu, instruksi dari alat sampai ke model, dan pengirimannya diterima. Kami juga merekam permintaan yang dikirim ChatAnthropic untuk memastikan bahwa adaptive thinking menyerahkan tool choice kepada model. Dengan model sungguhan, satu-satunya perbedaan adalah model yang memutuskan kapan memanggil alat, dan untuk itulah deskripsi dan paragraf tambahan tersebut dibuat. Endpoint mentah di balik kedua metode ini didokumentasikan di referensi API.

Kesalahan umum dan artinya

Apa yang Anda lihatPenyebabPerbaiki
Agen menunggu, menggulir, atau menyerah di halaman yang berisi CAPTCHA, dan tidak pernah memanggil alatPrompt sistem default menyatakan CAPTCHA dipecahkan secara otomatis, dan tidak ada yang mengoreksinyaBerikan extend_system_message berisi paragraf dari Langkah 2
Setiap langkah gagal dengan error 400 yang menyatakan tipe tool_choice tidak didukung untuk model tersebutChatAnthropic dibuat tanpa thinking, sehingga Browser Use memaksakan tool choiceBerikan thinking={"type": "adaptive"} ke ChatAnthropic
Sebuah langkah timeout setelah 180 detikPemecahan yang lambat ditambah pemanggilan model melampaui step_timeoutBerikan step_timeout=420 ke Agent, dan naikkan juga batas per aksi
Action solve_captcha timed out after 180s. The browser may be unresponsive (dead CDP WebSocket).Dengan step_timeout yang sudah dinaikkan, pemecahan melampaui batas per aksi; browser-nya baik-baik sajaSetel BROWSER_USE_ACTION_TIMEOUT_S di atas 300 sebelum Browser Use dimuat
Variabelnya sudah disetel, tetapi batasnya tetap 180 detikVariabel itu disetel setelah Agent atau Tools sudah di-importPindahkan penetapan nilainya ke bagian paling atas skrip utama, di atas setiap import yang memuat browser_use
Seluruh agen membeku selagi CAPTCHA dipecahkanKlien CapSkip yang sinkron memblokir event loop tempat koneksi browser berjalanGunakan AsyncCapSkip dan await setiap metodenya
Alat melaporkan bahwa tidak ada widget yang ditemukanHalaman merender widget dari skrip tanpa data-sitekey, menaruhnya di dalam iframe, atau memakai CAPTCHA yang berbedaBaca sitekey dari permintaan milik widget itu sendiri di DevTools, lalu kembangkan FIND dan FILL untuk halaman itu; keduanya berjalan di dokumen tingkat atas, jadi formulir di dalam iframe memerlukan pencariannya sendiri
Solved, but no response field to fillWidget Turnstile mengganti nama field-nya dengan data-response-field-name, atau menonaktifkannya dengan data-response-fieldBaca atribut itu di FIND dan tulis token ke field dengan nama tersebut
Token sudah terisi, tetapi situs tetap menolak pengirimanToken kedaluwarsa sebelum pengiriman, atau formulir menunggu callback yang didaftarkannya lewat skripMinta agen memecahkan CAPTCHA tepat sebelum mengirim, dan panggil callback milik halaman itu sendiri jika data-callback kosong
Halaman memakai reCAPTCHA v3 pada sebuah tombolFIND memperlakukannya sebagai v2Panggil solver.recaptcha dengan version v3 dan action milik halaman
Error dari alat berupa NetworkExceptionCapSkip tidak berjalan, atau host dan port-nya salah untuk tempat agen berjalanJalankan CapSkip, lalu periksa apakah ia harus berada di mode Local atau mode Server

FAQ

Apakah Browser Use memecahkan CAPTCHA dengan sendirinya?

Hanya di browser cloud-nya, tempat pemecahan terjadi di proxy milik Browser Use sendiri dan library menunggunya. Library open source-nya tidak menyertakan apa pun yang memecahkan CAPTCHA di browser yang Anda jalankan sendiri, baik itu Chromium lokal maupun Chrome milik Anda yang dijangkau melalui URL CDP. Untuk penyiapan itulah panduan ini dibuat.

Bisakah saya memberi agen server MCP CapSkip sebagai gantinya?

Bisa. Browser Use dapat memuat alat dari server MCP ke instance Tools miliknya, dan server MCP CapSkip menyediakan alat pemecahan untuk setiap tipe yang didukung. Namun, alat tersebut mengembalikan token, jadi model kemudian harus menuliskannya sendiri ke halaman dengan skrip buatannya sendiri. Itu berarti dua keputusan bagi model, bukan satu, dan keputusan kedua harus sesuai dengan markup setiap halaman. Alat kustom menjaga pembacaan dan penulisan halaman tetap di dalam kode. Jalur MCP cocok untuk agen yang tidak bisa Anda tambahi kode, dan halaman pemecah CAPTCHA MCP menunjukkan cara menghubungkannya.

Bagaimana dengan hCaptcha atau halaman challenge penuh Cloudflare?

CapSkip tidak memecahkan hCaptcha, itulah sebabnya FIND hanya mencocokkan class reCAPTCHA dan Turnstile dan tidak pernah mencocokkan widget h-captcha. Halaman challenge penuh Cloudflare adalah alur yang berbeda dari widget Turnstile: alur itu membutuhkan nilai cData dan chlPageData dari challenge tersebut serta user agent yang dikembalikan bersama token, dan halaman pemecah Cloudflare Turnstile menjelaskan hal itu. Karena itu, alat ini tidak mencakupnya dalam bentuknya sekarang. Tipe CapSkip lainnya, seperti GeeTest atau Capy Puzzle, dapat ditambahkan sebagai cabang tambahan di alat yang sama.

Bisakah agen yang berjalan di cloud menjangkau pemecah CAPTCHA saya?

Bisa. Alihkan CapSkip ke mode Server di pengaturan koneksi agar ia mendengarkan di alamat jaringan, bukan di loopback, baca alamat itu dari CAPSKIP_HOST di tempat agen berjalan, lalu berikan ke AsyncCapSkip. VPS, host container, runner CI, dan job terjadwal di platform cloud semuanya terhubung melalui API HTTP yang sama. Gunakan IP publik statis dan aturan firewall jika rutenya melewati internet. Pemecah CAPTCHA tetap berada di perangkat milik Anda, jadi agen yang berjalan lama dan menemui CAPTCHA di setiap halaman tidak memakan biaya tambahan apa pun.

Versi singkatnya

Penanganan CAPTCHA Browser Use di browser Anda sendiri pada dasarnya terdiri dari empat perubahan, ditambah perubahan kelima ketika agen pindah dari mesin pemecah CAPTCHA. Daftarkan alat solve_captcha yang membaca sitekey dengan page.evaluate, melakukan await pada AsyncCapSkip, lalu menulis token kembali ke halaman, sambil memanggil callback widget jika ada. Koreksi aturan default dengan extend_system_message agar agen memanggil alat itu tepat sebelum mengirim. Berikan adaptive thinking ke ChatAnthropic agar Claude menerima permintaannya. Naikkan BROWSER_USE_ACTION_TIMEOUT_S sebelum Browser Use dimuat dan step_timeout pada Agent, keduanya di atas 300 detik milik SDK. Dan alihkan CapSkip ke mode Server ketika agen berjalan di mana pun selain mesin pemecah CAPTCHA.

Agen yang menjelajah selama berjam-jam bisa menemui challenge di separuh halaman yang dikunjunginya, dan bypass captcha di mesin Windows Anda sendiri memecahkan semuanya tanpa biaya per pemecahan.