Cara Memecahkan CAPTCHA di Tes SeleniumBase (Python)

SeleniumBase mengendalikan browser. Ia tidak pernah membaca CAPTCHA untuk Anda. Jadi langkah captcha di SeleniumBase terdiri dari tiga gerakan: ambil sitekey dari halaman, minta token ke solver, lalu tulis token itu kembali ke formulir dan kirim. Pemecahannya terjadi di luar browser, dan itulah sebabnya kode yang sama bekerja pada run dengan tampilan, run headless, maupun job CI. Berikut wujudnya dalam dua format sintaksis yang paling mungkin Anda pakai.
Apa yang Anda butuhkan
- Python 3.10 atau lebih baru, dengan SeleniumBase dan SDK CapSkip sudah terinstal.
- Halaman yang benar-benar merender widget. Kunci uji reCAPTCHA milik Google sendiri selalu lolos, jadi kunci itu tidak membuktikan apa pun tentang kode Anda.
- CapSkip berjalan, entah dalam mode Local di alamat loopback atau dalam mode Server di mesin yang dapat dijangkau test runner Anda. Keduanya dijelaskan di pengaturan koneksi, dan pilihan mana yang Anda butuhkan bergantung pada tempat tes Anda dijalankan.
# Both packages, one command. pip install seleniumbase capskip
Apa yang dilakukan UC mode, dan apa yang tidak
SeleniumBase menyertakan UC mode, dan ada baiknya kita tegas soal tugasnya karena banyak orang memakainya sambil mengharapkan sebuah solver. UC mode mengurangi sinyal otomatisasi yang dibocorkan browser, dan GUI helper-nya bisa mengklik kotak centang pada halaman interstitial Cloudflare. Itu masalah yang berbeda dari menghasilkan token reCAPTCHA. Tidak ada satu pun bagian UC mode yang membaca gambar terdistorsi atau memilih ubin yang berisi bus.
# pip install seleniumbase
from seleniumbase import SB
with SB(uc=True) as sb:
# Disconnects the driver briefly so the page loads unobserved.
sb.uc_open_with_reconnect("https://example.com/protected", reconnect_time=3)
# Drives the real mouse pointer, so it needs a desktop session
# or a virtual display. It clicks a checkbox; it solves nothing.
sb.uc_gui_click_captcha()Ada dua konsekuensinya. GUI helper membutuhkan display sungguhan, sehingga tidak bisa dipakai di sebagian besar CI headless. Dan untuk reCAPTCHA serta GeeTest Anda tetap memerlukan token, dan itulah yang dibahas sisa artikel ini. Pakai keduanya bersamaan: UC mode untuk menekan seberapa sering Anda ditantang, dan solver untuk challenge yang tetap muncul.
Langkah 1: baca sitekey dari halaman
Sitekey bersifat publik. Nilainya menempel pada elemen widget sebagai atribut, dan SeleniumBase bisa membacanya dengan satu panggilan, jadi Anda tidak perlu menuliskannya secara permanen untuk tiap lingkungan.
# pip install seleniumbase
from seleniumbase import SB
PAGE = "https://example.com/page-with-recaptcha"
with SB() as sb:
sb.open(PAGE)
# Present on the widget div for v2, and on the script tag for v3.
sitekey = sb.get_attribute("[data-sitekey]", "data-sitekey")
print(sitekey) # this plus the page URL is all the solver needsLangkah 2: dapatkan token dari solver
Bagian ini sama sekali tidak berkaitan dengan SeleniumBase. Ini adalah panggilan Python biasa ke layanan di komputer Anda sendiri, dan ia mengembalikan string token yang akan dihasilkan halaman itu seandainya seorang manusia melewati widget-nya.
# pip install capskip
from capskip import CapSkip
solver = CapSkip(host="127.0.0.1", port=8080)
# v2 checkbox is the default shape. Pass invisible=1 or
# enterprise=1 for those variants, or version="v3" for v3.
result = solver.recaptcha(
sitekey=sitekey,
url=PAGE,
)
token = result["code"] # the value the form is waiting forClient yang sama menangani tipe lain yang mungkin Anda temui dalam sebuah test suite. Turnstile memakai solver.turnstile dengan sitekey dan URL halaman, GeeTest memakai solver.geetest dengan nilai gt dan challenge, dan CAPTCHA gambar memakai solver.normal dengan jalur file, sebuah URL, atau data URI base64. Halaman pemecah CAPTCHA Python membahas seluruh permukaan API-nya.
Langkah 3: suntikkan token dan kirim
Google menempatkan textarea tersembunyi di dalam formulir dan mengharapkan token ada pada nilainya. Tulis ke sana dengan panggilan script, lalu kirim formulirnya seperti yang akan dilakukan UI halaman itu sendiri.
# The response field is hidden, so a normal type() will not reach it.
sb.execute_script(
"document.getElementById('g-recaptcha-response').value = arguments[0];",
token,
)
sb.click("button[type='submit']")
sb.assert_element(".signup-success")Jika halaman menghubungkan fungsi callback-nya sendiri ke widget alih-alih membaca kolom saat pengiriman, panggil fungsi itu dengan token, bukan mengklik. Mana yang Anda perlukan terlihat di markup widget: atribut data-callback menyebutkan nama fungsinya, dan ketiadaannya berarti formulir membaca kolom tersebut.
Tes lengkapnya
Berikut keseluruhannya sebagai kelas BaseCase, yaitu format yang cocok dengan pytest suite yang sudah ada tanpa perkabelan tambahan.
# pip install seleniumbase capskip
from seleniumbase import BaseCase
from capskip import CapSkip
BaseCase.main(__name__, __file__)
PAGE = "https://example.com/page-with-recaptcha"
class RecaptchaTest(BaseCase):
def test_signup_form(self):
self.open(PAGE)
sitekey = self.get_attribute("[data-sitekey]", "data-sitekey")
solver = CapSkip(host="127.0.0.1", port=8080)
token = solver.recaptcha(sitekey=sitekey, url=PAGE)["code"]
self.execute_script(
"document.getElementById('g-recaptcha-response').value = arguments[0];",
token,
)
self.click("button[type='submit']")
self.assert_element(".signup-success")Pecahkan belakangan. Token reCAPTCHA hanya berlaku sekitar dua menit, jadi mengambilnya di awal tes lalu memakainya setelah empat langkah lain adalah balapan yang sesekali akan Anda kalahi. Letakkan pemecahan tepat sebelum pengiriman, dan di situ pula tempat percobaan ulang seharusnya berada.
Menjalankan solver di sebuah server
Test runner jarang berupa mesin tempat Anda duduk. CapSkip menangani itu dengan mode koneksi kedua, dan satu-satunya yang berubah di kode Anda adalah host-nya.
| Mode | Mendengarkan di | Gunakan saat |
|---|---|---|
| Lokal | 127.0.0.1, hanya perangkat itu | Tes dan solver berjalan di satu mesin |
| Server | Alamat jaringan atau IP publik Anda | Runner CI, sebuah VPS, atau test grid memanggil masuk |
# pip install capskip
import os
from capskip import CapSkip
# The SDK reads these names from the environment too, so one test
# file runs unchanged on a laptop and on a shared runner.
solver = CapSkip(
host=os.environ.get("CAPSKIP_HOST", "127.0.0.1"),
port=int(os.environ.get("CAPSKIP_PORT", "8080")),
)IP publik statis disarankan ketika pemanggilnya berada di luar jaringan Anda sendiri. Mode Server tetap perangkat keras milik Anda dan tetap tanpa kuota: yang berubah adalah tempat solver berjalan, bukan siapa pemiliknya atau berapa biayanya per pemecahan. Seluruh pilihannya ada di pengaturan koneksi.
Kesalahan umum
| Apa yang Anda lihat | Penyebab | Perbaiki |
|---|---|---|
| NetworkException | Tidak ada yang mendengarkan di host dan port tersebut | Jalankan CapSkip, atau arahkan host ke server yang menjalankannya |
| TimeoutException | Polling melewati recaptchaTimeout | Naikkan timeout-nya, atau pastikan sitekey yang dipakai adalah yang aktif |
| ERROR_GOOGLEKEY | Sitekey tidak pernah sampai atau formatnya salah | Cetak apa yang dikembalikan get_attribute sebelum Anda mengirimnya |
| ERROR_PAGEURL | URL halaman hilang atau bukan URL lengkap | Kirim URL absolut yang sama dengan yang sedang dibuka browser |
| Formulir menolak token yang valid | Halaman memakai callback, bukan kolomnya | Panggil fungsi data-callback dengan token tersebut |
Setiap kode yang dapat dikembalikan API tercantum di dokumentasi API CapSkip, beserta pemicu masing-masing.
FAQ
Apakah UC mode memecahkan reCAPTCHA dengan sendirinya?
Tidak. UC mode membuat browser tampak kurang otomatis dan bisa mengklik kotak centang pada interstitial Cloudflare lewat GUI helper. Keduanya sama sekali tidak menghasilkan token reCAPTCHA. Anda tetap mengambil token dari solver dan menuliskannya ke formulir, persis seperti yang ditunjukkan di atas. Jalankan keduanya: UC mode menekan seberapa sering Anda ditantang, dan solver menyelesaikan challenge yang tetap Anda terima.
Bisakah saya menjalankannya secara headless di CI?
Bisa, karena pemecahannya tidak pernah menyentuh browser. Berikan headless ke SB atau tambahkan flag-nya di baris perintah pytest, dan ketiga langkahnya tetap sama. Bagian yang tidak bertahan di runner headless adalah klik GUI milik UC mode, yang menggerakkan penunjuk mouse sungguhan dan membutuhkan sesi desktop atau display virtual.
Tes saya berjalan di runner Linux. Di mana solver-nya ditempatkan?
Di mesin Windows yang Anda kendalikan, dijangkau lewat mode Server. CapSkip adalah aplikasi Windows, jadi polanya adalah satu instance solver di mesin Windows dan sebanyak apa pun runner yang mengarah ke sana lewat API. Setel CAPSKIP_HOST di runner dan tidak ada lagi yang berubah di dalam tes.
Apakah saya perlu proxy agar pemecahannya cocok dengan browser saya?
Kadang perlu, dan hal itu didukung untuk reCAPTCHA, Turnstile, serta GeeTest. Berikan dictionary proxy berisi type dan URI, maka pemecahan dilakukan melaluinya, dan ini penting ketika situs mempermasalahkan apakah token dan sesi berasal dari alamat yang sama. CAPTCHA gambar tidak menerima proxy, karena tidak ada bagian darinya yang terikat pada jalur jaringan.
Versi singkatnya
Baca sitekey dengan get_attribute, ambil token-nya, tuliskan ke kolom respons tersembunyi, lalu kirim. Jaga agar pemecahan berada di langkah yang sama dengan pengiriman supaya token-nya masih segar, dan simpan host di variabel lingkungan supaya suite berjalan sama di mana pun. Untuk gambaran Selenium yang lebih luas, lihat halaman pemecah CAPTCHA Selenium, dan untuk hal khusus v2 lihat halaman pemecah reCAPTCHA v2. Tersisa soal biaya, dan di situlah suite yang berjalan pada setiap commit paling terasa menyakitkan: pemecah captcha lokal berarti setiap pemecahan terjadi di perangkat keras yang sudah Anda miliki, tanpa kuota, sesering apa pun tes dijalankan.
