Panduan
Klik gambar reCAPTCHA dengan Selenium
Halaman ini diterjemahkan otomatis dari versi bahasa Mandarin dan mungkin mengandung kesalahan. Versi bahasa Mandarin menjadi acuan utama.
Tutorial ini membuka halaman demo reCAPTCHA Google dengan Selenium 4 dan menyelesaikan soal gambar di browser sungguhan: membaca pertanyaan dan gambar, menyerahkannya ke pengenalan gambar reCAPTCHA v2 (ReCaptchaV2Classification) untuk menentukan kotak mana yang harus diklik, lalu mensimulasikan kliknya. Berbeda dengan cara mengambil token, verifikasi di sini diselesaikan langsung di browser, sehingga cocok untuk situs yang tingkat keberhasilan token-nya rendah.
Jika tidak ingin menulis kode, gunakan langsung ekstensi browser, yang mengklik secara otomatis dengan API yang sama.
Persiapan
Section titled “Persiapan”pip install requests selenium pillowexport YESCAPTCHA_CLIENT_KEY=your_client_keyChrome harus sudah terpasang. Selenium 4 akan mengunduh chromedriver yang sesuai secara otomatis.
- Klik kotak centang. Kotak centang berada di dalam iframe dengan
title="reCAPTCHA"; pindah ke iframe tersebut, lalu klik#recaptcha-anchor. - Pindah ke iframe soal. Soal berada di iframe lain (title mengandung “challenge”).
- Baca pertanyaan. Teks tebal di
.rc-imageselect-desc-wrapper strongadalah target yang dicari, misalnya “traffic lights”. API membutuhkan ID pertanyaan, jadi ubah nama menjadi ID (/m/015qff) dengan tabel padanan, lihat ID pertanyaan. Antarmuka browser berbahasa Inggris paling mudah untuk dicocokkan. - Ambil gambar. Gambar di setiap kotak sebenarnya berasal dari satu gambar besar yang sama; unduh
srcdaritd.rc-imageselect-tile img. Untuk 9 kotak (3x3), ubah ukuran menjadi 300×300; untuk 16 kotak (4x4), ubah menjadi 450×450, lalu konversi ke Base64. - Kenali. Panggil
createTaskdengan jenis tugasReCaptchaV2Classification, kirimimagedanquestion. Tambahkan"confidence": 0.5, maka gambar 3x3 akan mengembalikan semua kotak yang sesuai sekaligus, sehingga Anda tidak perlu menangani gambar kecil yang muncul setelah klik. - Klik.
objectsyang dikembalikan adalah nomor kotak, dimulai dari 0, dari kiri ke kanan dan dari atas ke bawah; kliktdyang sesuai satu per satu. - Verifikasi. Klik
#recaptcha-verify-button. Jika muncul putaran soal baru, kembali ke langkah 3; jika jendela soal tertutup, berarti sudah lolos. - Kirim formulir. Kembali ke halaman utama, lalu klik tombol kirim.
Kode lengkap
Section titled “Kode lengkap”"""Click through a reCAPTCHA v2 image challenge with Selenium 4 and ReCaptchaV2Classification.
Flow: open the page -> click the checkbox -> read the target name and the grid image ->ask YesCaptcha which tiles to click -> click them -> press Verify. Repeat if a new challenge appears.
Run: pip install requests selenium pillow export YESCAPTCHA_CLIENT_KEY=your_client_key python recaptcha_click_selenium.pyEach recognized image is charged (see the price list). reCAPTCHA's page structure can change;adjust the selectors below if a step stops working."""import base64import ioimport osimport time
import requestsfrom PIL import Imagefrom selenium import webdriverfrom selenium.webdriver.common.by import Byfrom selenium.webdriver.support import expected_conditions as ECfrom selenium.webdriver.support.wait import WebDriverWait
CLIENT_KEY = os.environ["YESCAPTCHA_CLIENT_KEY"]PAGE_URL = "https://www.google.com/recaptcha/api2/demo"
# Target names shown in the challenge (English UI) -> question IDs.# Full list: https://docs.yescaptcha.com/en/tasks/recaptcha-classification/QUESTION_IDS = { "taxis": "/m/0pg52", "bus": "/m/01bjv", "buses": "/m/01bjv", "motorcycles": "/m/04_sv", "tractors": "/m/013xlm", "chimneys": "/m/01jk_4", "crosswalks": "/m/014xcs", "traffic lights": "/m/015qff", "bicycles": "/m/0199g", "parking meters": "/m/015qbp", "cars": "/m/0k4j", "bridges": "/m/015kr", "boats": "/m/019jd", "palm trees": "/m/0cdl1", "mountains or hills": "/m/09d_r", "fire hydrants": "/m/01pns0", "a fire hydrant": "/m/01pns0", "stairs": "/m/01lynh",}
def classify(image_b64, question): task = {"type": "ReCaptchaV2Classification", "image": image_b64, "question": question, "confidence": 0.5} data = requests.post( "https://api.yescaptcha.com/createTask", json={"clientKey": CLIENT_KEY, "task": task}, timeout=30, ).json() if data.get("errorId"): raise RuntimeError(f"{data.get('errorCode')}: {data.get('errorDescription')}") return data["solution"] # synchronous: the solution comes back right away
def grid_image_b64(url, size): """Download the challenge image and scale it to the standard size (300 for 3x3, 450 for 4x4).""" img = Image.open(io.BytesIO(requests.get(url, timeout=30).content)).convert("RGB") img = img.resize((size, size)) buf = io.BytesIO() img.save(buf, format="JPEG") return base64.b64encode(buf.getvalue()).decode()
driver = webdriver.Chrome()wait = WebDriverWait(driver, 15)try: driver.get(PAGE_URL)
# 1. Click the checkbox (inside the "reCAPTCHA" iframe) wait.until(EC.frame_to_be_available_and_switch_to_it((By.CSS_SELECTOR, 'iframe[title="reCAPTCHA"]'))) wait.until(EC.element_to_be_clickable((By.ID, "recaptcha-anchor"))).click() driver.switch_to.default_content()
# 2. Switch to the challenge iframe and solve rounds until it closes wait.until(EC.frame_to_be_available_and_switch_to_it( (By.XPATH, '//iframe[contains(@title, "challenge")]'))) for _ in range(5): target = wait.until(EC.presence_of_element_located( (By.CSS_SELECTOR, ".rc-imageselect-desc-wrapper strong"))).text.strip().lower() question = QUESTION_IDS.get(target) if not question: print("unsupported target, reloading:", target) driver.find_element(By.ID, "recaptcha-reload-button").click() time.sleep(2) continue tiles = driver.find_elements(By.CSS_SELECTOR, "td.rc-imageselect-tile") size = 450 if len(tiles) == 16 else 300 url = driver.find_element(By.CSS_SELECTOR, "td.rc-imageselect-tile img").get_attribute("src") solution = classify(grid_image_b64(url, size), question) for index in solution.get("objects", []): tiles[index].click() time.sleep(0.3) time.sleep(1) driver.find_element(By.ID, "recaptcha-verify-button").click() time.sleep(3) driver.switch_to.default_content() frame = driver.find_element(By.XPATH, '//iframe[contains(@title, "challenge")]') if not frame.is_displayed(): # challenge closed: passed break driver.switch_to.frame(frame)
driver.switch_to.default_content() driver.find_element(By.ID, "recaptcha-demo-submit").click() time.sleep(2) print("passed" if "Verification Success" in driver.page_source else "not passed")finally: driver.quit()Catatan
Section titled “Catatan”- Struktur halaman reCAPTCHA bisa berubah; jika selector di kode tidak berfungsi lagi, sesuaikan dengan halaman yang sebenarnya.
- Setiap pengenalan satu gambar dikenai pemotongan poin (harga ada di pengenalan gambar reCAPTCHA v2). Tugas yang gagal verifikasi setelah diklik dapat dilaporkan dalam 1 jam untuk mengajukan pengembalian poin setelah laporan.
- Jika menemukan pertanyaan yang tidak ada di tabel padanan, klik tombol refresh untuk mengganti soal, atau hubungi Dukungan agar ditambahkan.