Tutorial

pengaturan token GeeTest dalam Browser Automation

GeeTest v3 mengembalikan tiga nilai setelah solve: geetest_challenge, geetest_validate, dan geetest_seccode. Menyuntikkan ketiganya dengan benar ke dalam sesi browser automation memerlukan pemahaman di mana situs mengharapkannya — field form tersembunyi, JavaScript callback, atau XHR payload. Berikut cara melakukannya di setiap framework utama.

Apa yang Anda Suntikkan

CaptchaAI mengembalikan hasil tiga bagian:

{
  "geetest_challenge": "a1b2c3d4e5...modified_challenge",
  "geetest_validate": "abc123def456_validate",
  "geetest_seccode": "abc123def456_validate|jordan"
}

Ketiga nilai tersebut harus disuntikkan. Hilangnya salah satu menyebabkan kegagalan verifikasi.

Langkah 1: Ekstrak Parameter dan Solve

Umum untuk semua framework — ekstrak gt dan challenge, lalu solve dengan CaptchaAI:

import requests
import time

def solve_geetest(gt, challenge, page_url):
    resp = requests.post("https://ocr.captchaai.com/in.php", data={
        "key": "YOUR_API_KEY",
        "method": "geetest",
        "gt": gt,
        "challenge": challenge,
        "pageurl": page_url,
        "json": 1
    })
    task_id = resp.json()["request"]

    for _ in range(60):
        time.sleep(3)
        result = requests.get("https://ocr.captchaai.com/res.php", params={
            "key": "YOUR_API_KEY",
            "action": "get",
            "id": task_id,
            "json": 1
        })
        data = result.json()
        if data["status"] == 1:
            return data["request"]  # Returns dict with three values
    raise TimeoutError("GeeTest solve timed out")

Langkah 2: Injeksi ke Playwright (Python)

Ekstrak Parameter

from playwright.sync_api import sync_playwright

with sync_playwright() as p:
    browser = p.chromium.launch(headless=False)
    page = browser.new_page()

    # Capture GeeTest registration response
    geetest_data = {}
    def capture_geetest(response):
        if "register" in response.url and response.status == 200:
            try:
                data = response.json()
                if "gt" in data and "challenge" in data:
                    geetest_data.update(data)
            except Exception:
                pass

    page.on("response", capture_geetest)
    page.goto("https://staging.example.com/qa-login")
    page.wait_for_selector(".geetest_holder")

    gt = geetest_data["gt"]
    challenge = geetest_data["challenge"]

Injeksi Solusi

# Solve with CaptchaAI
solution = solve_geetest(gt, challenge, page.url)

# Method 1: Set hidden form fields
page.evaluate(f"""
    const fields = {{
        'geetest_challenge': '{solution["geetest_challenge"]}',
        'geetest_validate': '{solution["geetest_validate"]}',
        'geetest_seccode': '{solution["geetest_seccode"]}'
    }};
    for (const [name, value] of Object.entries(fields)) {{
        let input = document.querySelector(`input[name="${{name}}"]`);
        if (!input) {{
            input = document.createElement('input');
            input.type = 'hidden';
            input.name = name;
            document.querySelector('form').appendChild(input);
        }}
        input.value = value;
    }}
""")

# Submit form
page.click("#submit-button")

Metode 2: Trigger JavaScript Callback

Beberapa situs menggunakan JavaScript callback GeeTest alih-alih form field:

page.evaluate(f"""
    // Find the GeeTest captcha object
    if (window.captchaObj) {{
        // Simulate a successful solve
        const result = {{
            geetest_challenge: '{solution["geetest_challenge"]}',
            geetest_validate: '{solution["geetest_validate"]}',
            geetest_seccode: '{solution["geetest_seccode"]}'
        }};

        // Override getValidate to return our solution
        window.captchaObj.getValidate = function() {{ return result; }};

        // Trigger the success callback
        const successEvent = new Event('geetest_success');
        document.dispatchEvent(successEvent);
    }}
""")

Langkah 3: Injeksi ke Puppeteer (JavaScript)

const puppeteer = require('puppeteer');

async function solveAndInject() {
  const browser = await puppeteer.launch({ headless: false });
  const page = await browser.newPage();

  // Capture GeeTest params
  let gt, challenge;
  page.on('response', async (response) => {
    if (response.url().includes('register') && response.status() === 200) {
      try {
        const data = await response.json();
        if (data.gt && data.challenge) {
          gt = data.gt;
          challenge = data.challenge;
        }
      } catch (e) {}
    }
  });

  await page.goto('https://staging.example.com/qa-login');
  await page.waitForSelector('.geetest_holder');

  // Solve with CaptchaAI (implementation from earlier)
  const solution = await solveCaptcha(gt, challenge, page.url());

  // Inject the three values
  await page.evaluate((sol) => {
    // Set hidden inputs
    const form = document.querySelector('form');
    ['geetest_challenge', 'geetest_validate', 'geetest_seccode'].forEach(name => {
      let input = document.querySelector(`input[name="${name}"]`);
      if (!input) {
        input = document.createElement('input');
        input.type = 'hidden';
        input.name = name;
        form.appendChild(input);
      }
      input.value = sol[name];
    });
  }, solution);

  await page.click('#submit-button');
}

Langkah 4: Injeksi ke Selenium (Python)

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

driver = webdriver.Chrome()
driver.get("https://staging.example.com/qa-login")

# Wait for GeeTest widget
WebDriverWait(driver, 15).until(
    EC.presence_of_element_located((By.CLASS_NAME, "geetest_holder"))
)

# Extract gt and challenge from the page
gt = driver.execute_script(
    "return document.querySelector('[data-gt]')?.dataset.gt"
)
challenge = driver.execute_script(
    "return document.querySelector('[data-challenge]')?.dataset.challenge"
)

# Solve with CaptchaAI
solution = solve_geetest(gt, challenge, driver.current_url)

# Inject via JavaScript
driver.execute_script(f"""
    var fields = {{
        'geetest_challenge': '{solution["geetest_challenge"]}',
        'geetest_validate': '{solution["geetest_validate"]}',
        'geetest_seccode': '{solution["geetest_seccode"]}'
    }};
    var form = document.querySelector('form');
    for (var name in fields) {{
        var input = document.querySelector('input[name="' + name + '"]');
        if (!input) {{
            input = document.createElement('input');
            input.type = 'hidden';
            input.name = name;
            form.appendChild(input);
        }}
        input.value = fields[name];
    }}
""")

driver.find_element(By.ID, "submit-button").click()

Menangani Submit Berbasis XHR

Beberapa situs mengirimkan hasil GeeTest via XHR, bukan form POST. Intercept dan ubah request:

# Playwright: Intercept the XHR and inject values
def handle_route(route):
    if "login" in route.request.url and route.request.method == "POST":
        # Modify the POST data to include our solution
        post_data = route.request.post_data
        # Add GeeTest values to the request
        route.continue_(post_data=modified_data)
    else:
        route.continue_()

page.route("**/api/login**", handle_route)

Pemecahan Masalah

Masalah Penyebab Perbaikan
"GeeTest validation failed" Satu dari tiga nilai tidak ada Verifikasi ketiganya disuntikkan
Challenge kedaluwarsa sebelum injeksi Jeda terlalu lama antara ekstraksi dan solve Ekstrak dan solve secara berurutan
Form submit tapi nilai tidak disertakan Nama field atau selector form salah Cek form sesungguhnya untuk nama yang benar
Callback tidak terpicu Situs menggunakan nama callback kustom Temukan callback di opsi initGeetest
Nilai disuntikkan tapi widget masih tampil State widget tidak diperbarui Trigger success callback secara programatik

Pertanyaan Umum

Apakah saya perlu menyembunyikan widget GeeTest secara visual setelah injeksi?

Tidak. State visual widget tidak mempengaruhi submit form. Selama ketiga nilai ada dalam data form, server akan memvalidasinya terlepas dari tampilan widget.

Bisakah saya menyuntikkan nilai GeeTest tanpa browser?

Ya, jika situs menerima HTTP POST langsung dengan ketiga nilai tersebut. Intercept endpoint submit form dan kirimkan via requests atau HTTP client lainnya.

Mengapa GeeTest menggunakan tiga nilai terpisah, bukan satu token?

Ketiga nilai memiliki tujuan berbeda: geetest_challenge melacak sesi, geetest_validate membuktikan challenge telah diselesaikan, dan geetest_seccode menyediakan hash untuk deteksi tampering.

Artikel Terkait

  • Solving GeeTest v3 dengan Node.js dan CaptchaAI
  • CAPTCHA Solving di Mobile Browser Automation

Langkah Selanjutnya

Menyuntikkan solusi GeeTest dalam kerangka apa pun —dapatkan kunci API CaptchaAI Andadan mulai menyelesaikannya.

Komentar dinonaktifkan untuk artikel ini.