Scarnox · Blog

Solver captcha Selenium di Python: contoh yang berfungsi (2026)

Selenium menjalankan browser sungguhan, jadi halaman dirender dan skripnya berjalan seperti yang akan dilakukan manusia. Satu-satunya langkah yang tidak bisa dilakukannya adalah memecahkan widget PopularCaptcha. Panduan ini menambahkan langkah itu: baca sitekey dari halaman yang sudah dirender, dapatkan token dengan satu panggilan API, tulis token ke dalam form, lalu kirim.

Panduan ini mencakup widget PopularCaptcha, yang saat ini dipecahkan Scarnox secara proxyless. Mulai dengan kredit uji coba gratis, tanpa kartu dan coba skripnya pada form uji terlebih dahulu.

Apa yang harus dilakukan Selenium

Alurnya memiliki empat bagian:

  1. Muat halaman dan tunggu widget dirender.
  2. Baca atribut data-sitekey dari widget.
  3. Dapatkan token dari API dan masukkan ke form.
  4. Kirim form sebelum token kedaluwarsa.

Langkah ketiga adalah satu-satunya yang menyentuh captcha. Sisanya adalah pekerjaan Selenium biasa.

Instal paketnya

pip install selenium requests

Selenium 4.6 dan yang lebih baru menemukan ChromeDriver yang cocok sendiri, jadi Anda tidak perlu mengunduh driver secara manual.

Skrip lengkap

import requests
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait

API_KEY = "scarnox_YOURAPIKEY"
API_URL = "https://api.scarnox.com/api/tasks/create"
PAGE_URL = "https://example.com/signup"


def solve(sitekey: str, page_url: str, invisible: bool = False) -> str:
    body = {
        "captcha_type": "PopularCaptchaTaskProxyless",
        "site_key": sitekey,
        "site_url": page_url,
    }
    if invisible:
        body["is_invisible"] = True

    r = requests.post(
        API_URL,
        headers={"Authorization": f"Bearer {API_KEY}"},
        json=body,
        timeout=185,  # menunggu sampai token siap
    )
    data = r.json()
    if data.get("errorId") != 0:
        raise RuntimeError(f"{data.get('errorCode')}: {data.get('errorDescription')}")
    return data["solution"]["token"]


INJECT_TOKEN_JS = """
const token = arguments[0];
let field = document.querySelector('[name="h-captcha-response"]');
if (!field) {
    field = document.createElement("textarea");
    field.name = "h-captcha-response";
    field.style.display = "none";
    document.querySelector("form").appendChild(field);
}
field.value = token;
let extra = document.querySelector('[name="g-recaptcha-response"]');
if (!extra) {
    extra = document.createElement("textarea");
    extra.name = "g-recaptcha-response";
    extra.style.display = "none";
    document.querySelector("form").appendChild(extra);
}
extra.value = token;
"""


def main() -> None:
    driver = webdriver.Chrome()
    try:
        driver.get(PAGE_URL)

        widget = WebDriverWait(driver, 15).until(
            EC.presence_of_element_located((By.CSS_SELECTOR, "[data-sitekey]"))
        )
        sitekey = widget.get_attribute("data-sitekey")
        invisible = widget.get_attribute("data-size") == "invisible"

        token = solve(sitekey, driver.current_url, invisible=invisible)

        # Isi field lain terlebih dahulu, lalu sisipkan token tepat sebelum kirim,
        # karena token kedaluwarsa dalam sekitar dua menit.
        driver.find_element(By.NAME, "email").send_keys("you@example.com")
        driver.execute_script(INJECT_TOKEN_JS, token)

        driver.find_element(By.CSS_SELECTOR, "form button[type=submit]").click()
        WebDriverWait(driver, 15).until(EC.url_changes(PAGE_URL))
        print("Terkirim. Sekarang di:", driver.current_url)
    finally:
        driver.quit()


if __name__ == "__main__":
    main()

Skrip ini tidak membutuhkan proxy untuk solve PopularCaptcha proxyless. Hapus field proxy dan biarkan situs melihat koneksi normal Anda.

Urutan operasi adalah bagian yang paling sering salah. Isi sisa form terlebih dahulu, lalu solve, lalu sisipkan, lalu klik. Jika Anda memecahkan sebelum mengetik di field lain, halaman atau form yang lambat bisa membuat pengiriman melewati masa berlaku token. Jaga jarak antara solve dan klik sependek mungkin, dan periksa halaman hasil untuk error sebelum Anda menganggap captcha sudah lolos.

Mengapa token dimasukkan dengan JavaScript

Sebagian besar widget PopularCaptcha menuliskan token ke textarea tersembunyi bernama h-captcha-response ketika seseorang memecahkannya. Karena Selenium tidak pernah melihat orang itu, skrip menuliskan field yang sama sendiri. Cuplikan INJECT_TOKEN_JS melakukan dua hal:

Ia juga mengisi g-recaptcha-response, karena banyak situs membaca nama itu untuk kompatibilitas.

Widget tak terlihat

Widget tak terlihat tidak memiliki kotak centang. Ia berjalan di latar belakang dan biasanya dipicu saat form dikirim. Skrip memeriksa data-size="invisible" dan mengirim is_invisible: true ketika menemukannya. Beberapa situs juga melampirkan callback JavaScript ke widget. Jika form tetap diam setelah Anda menyisipkan token, cari atribut data-callback dan panggil fungsi tersebut dengan token. Panduan kami tentang captcha tak terlihat membahas kasus ini.

Menggunakannya dalam pengujian

Selenium juga merupakan alat yang umum untuk pengujian end-to-end. Jika situs staging Anda sendiri menampilkan captcha, kode yang sama memungkinkan pengujian melewatinya. Jaga lingkungan pengujian terpisah dari produksi, dan jangan menjalankannya terhadap situs yang bukan milik Anda. Penyiapan untuk suite pengujian ada di captcha dalam pengujian otomatis.

Masalah umum

Harga

Anda membayar per solve yang berhasil. Solve yang gagal tidak ditagih. Lihat harga terkini untuk tarifnya, dan mulai dengan kredit uji coba gratis, tanpa kartu.

Langkah selanjutnya