API Tutorials

Cara Solve Grid Image CAPTCHA Secara Otomatis

Ketika skrip scraping Anda tersendat di sebuah gambar yang dibagi menjadi kotak-kotak 3×3 lalu diminta "pilih semua sel yang berisi lampu lalu lintas", Anda sedang berhadapan dengan grid image CAPTCHA. Cara menyelesaikannya secara otomatis sebenarnya ringkas: ambil satu screenshot grid penuh, kirim gambar itu ke API CaptchaAI, tunggu hasilnya lewat polling, lalu klik sel yang ditunjuk. Panduan ini memandu seluruh alur tersebut dengan kode Python dan Node.js yang bisa langsung dipakai.

Fokusnya adalah grid challenge non-reCAPTCHA — gambar tunggal yang dibagi menjadi grid — yang diselesaikan lewat endpoint in.php dengan method=post dan parameter recaptcha=1.


Grid image CAPTCHA vs reCAPTCHA: mana yang Anda hadapi

Sebelum menulis kode, pastikan dulu jenis grid yang muncul, karena keduanya butuh metode berbeda:

  • Custom grid statis. Banyak situs memakai gambar besar tunggal yang dibagi menjadi grid dan tidak berubah setelah Anda klik. Inilah target panduan ini — Anda menangkap satu gambar, mengirimnya, dan mendapatkan daftar sel yang harus diklik.
  • reCAPTCHA grid dinamis. Pada reCAPTCHA milik Google, tile yang Anda klik kerap diganti dengan gambar baru sampai tidak ada lagi yang cocok. Grid semacam ini tidak diselesaikan sebagai satu gambar statis; gunakan metode token (method=userrecaptcha), bukan metode post.

Aturan praktisnya: kalau gambar tetap sama sesudah diklik, pakai alur di bawah ini. Kalau tile-nya berganti, itu ranah reCAPTCHA dan butuh pendekatan token.


Prasyarat

Item Nilai
API key CaptchaAI Dari halaman utama CaptchaAI
Gambar grid Screenshot atau base64 dari grid penuh
Bahasa Python 3.7+ atau Node.js 14+

Alur kerjanya mengikuti pola empat langkah yang sama seperti tugas solver lain: kirim gambar → simpan task ID → polling hasil → pakai solusi.


Langkah 1: Ambil gambar grid

Kualitas gambar menentukan hasil. Ambil grid pada resolusi penuh dan pastikan seluruh sel masuk dalam satu frame.

Metode A: Screenshot elemen captcha

from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()
driver.get("https://example.com/protected-form")

# Screenshot just the captcha container
captcha_element = driver.find_element(By.CSS_SELECTOR, "#captcha-container")
captcha_element.screenshot("captcha_grid.png")

Metode B: Ekstrak gambar dari atribut src

Jika grid dimuat sebagai gambar biasa, ambil langsung dari atribut src — sudah berupa base64 bila memakai skema data:image, atau unduh bila berupa URL:

import base64
import requests

captcha_img = driver.find_element(By.CSS_SELECTOR, ".grid-captcha img")
src = captcha_img.get_attribute("src")

if src.startswith("data:image"):
    image_b64 = src.split(",")[1]
else:
    image_data = requests.get(src).content
    image_b64 = base64.b64encode(image_data).decode()

Langkah 2: Kirim gambar ke CaptchaAI

Kirim gambar ke in.php. Anda bisa memakai unggahan file langsung atau string base64 — keduanya memberi hasil yang sama.

Menggunakan unggahan file (Python)

import requests
import time

API_KEY = "YOUR_API_KEY"

with open("captcha_grid.png", "rb") as f:
    response = requests.post("https://ocr.captchaai.com/in.php",
        data={
            "key": API_KEY,
            "method": "post",
            "recaptcha": 1,
            "json": 1
        },
        files={"file": f}
    )

data = response.json()
task_id = data["request"]
print(f"Task: {task_id}")

Menggunakan base64 (Python)

response = requests.post("https://ocr.captchaai.com/in.php", data={
    "key": API_KEY,
    "method": "post",
    "body": image_b64,
    "recaptcha": 1,
    "json": 1
})

task_id = response.json()["request"]

Node.js

const axios = require('axios');
const fs = require('fs');

async function submitGridCaptcha(imagePath) {
  const imageB64 = fs.readFileSync(imagePath).toString('base64');

  const { data } = await axios.post('https://ocr.captchaai.com/in.php', null, {
    params: {
      key: 'YOUR_API_KEY',
      method: 'post',
      body: imageB64,
      recaptcha: 1,
      json: 1
    }
  });

  return data.request;
}

Simpan task_id yang dikembalikan — inilah tanda pengenal task yang Anda pakai untuk mengambil hasil.


Langkah 3: Polling hasil

Solusi tidak datang seketika. Lakukan polling ke res.php dengan jeda beberapa detik sampai statusnya siap. Contoh di bawah mencoba hingga 30 kali dengan jeda 5 detik:

def get_grid_solution(task_id):
    for _ in range(30):
        time.sleep(5)
        result = requests.get("https://ocr.captchaai.com/res.php", params={
            "key": API_KEY,
            "action": "get",
            "id": task_id,
            "json": 1
        }).json()

        if result.get("status") == 1:
            return result["request"]
        if result.get("request") != "CAPCHA_NOT_READY":
            raise Exception(f"Error: {result['request']}")

    raise Exception("Timeout")

solution = get_grid_solution(task_id)
print(f"Solution: {solution}")
# Returns click coordinates or cell indices

Selama respons masih CAPCHA_NOT_READY, artinya task belum selesai — lanjutkan polling. Kode error lain berarti gambar bermasalah dan sebaiknya dihentikan.


Langkah 4: Terapkan solusi

Hasil bisa berbentuk indeks sel (misalnya 2,5,6) atau koordinat piksel (misalnya x=120,y=80;x=250,y=200). Tangani keduanya dengan blok yang sesuai.

Klik berdasarkan indeks sel

# If solution returns cell indices (e.g., "2,5,6")
selected = [int(i) for i in solution.split(",")]
cells = driver.find_elements(By.CSS_SELECTOR, ".grid-cell")

for idx in selected:
    cells[idx - 1].click()
    time.sleep(0.2)

driver.find_element(By.CSS_SELECTOR, ".verify-button").click()

Klik berdasarkan koordinat

from selenium.webdriver.common.action_chains import ActionChains

# If solution returns coordinates (e.g., "x=120,y=80;x=250,y=200")
captcha_element = driver.find_element(By.CSS_SELECTOR, "#captcha-container")
actions = ActionChains(driver)

for coord in solution.split(";"):
    parts = dict(p.split("=") for p in coord.split(","))
    x, y = int(parts["x"]), int(parts["y"])
    actions.move_to_element_with_offset(captcha_element, x, y).click()

actions.perform()

Contoh skenario: agregasi harga dari katalog supplier

Bayangkan sebuah tim price-monitoring di Jakarta yang menarik data katalog dari portal supplier terotorisasi, dan portal itu memasang custom grid challenge pada halaman login internal. Worker scraping yang berjalan di region ap-southeast-1 (Singapura) menangkap grid, mengirimnya ke CaptchaAI, lalu meneruskan sesi begitu solusi kembali. Karena penagihan CaptchaAI berbasis thread — bukan per solve — biaya tetap terprediksi walau volume naik saat katalog diperbarui massal. Paket BASIC ($15/bulan, 5 thread) cukup untuk beban kecil, dan Anda bisa naik ke ADVANCE ($90/bulan, 50 thread) ketika perlu menjalankan banyak worker paralel.

Satu catatan kepatuhan: sesuai UU Pelindungan Data Pribadi (UU 27/2022), scrape hanya data yang memang berhak Anda proses dan hindari data pribadi milik pihak lain.


Mengatasi error umum

Error Penyebab Solusi
ERROR_WRONG_FILE_EXTENSION Format gambar tidak valid Gunakan PNG atau JPEG; pastikan base64 valid
ERROR_CAPTCHA_UNSOLVABLE Gambar terlalu kecil atau buram Ambil ulang pada resolusi penuh
Sel yang salah dipilih Format solusi tidak cocok Cek apakah solusi berupa indeks atau koordinat
ERROR_TOO_BIG_CAPTCHA_FILESIZE Gambar melampaui batas ukuran Perkecil hingga di bawah 600KB

Contoh lengkap yang dapat dijalankan

Butuh proyek kerja utuh dengan pengaturan environment, polling, percobaan ulang, dan penanganan error?

Lihat contoh lengkap yang dapat dijalankan di GitHub →


Pertanyaan umum

Bagaimana cara tahu solusi berupa indeks sel atau koordinat?

Periksa bentuk string yang dikembalikan. Nilai seperti 2,5,6 adalah indeks sel, sedangkan x=120,y=80;x=250,y=200 adalah koordinat piksel. Kode di Langkah 4 sudah menyediakan cabang untuk masing-masing format, jadi cukup arahkan solusi ke blok yang cocok.

Berapa biaya menyelesaikan grid image CAPTCHA di CaptchaAI?

Penagihan berbasis thread, bukan per solve. Paket BASIC seharga $15/bulan memberi 5 thread dengan solve tak terbatas per thread; ADVANCE $90/bulan memberi 50 thread untuk beban paralel yang lebih besar. Tidak ada biaya tambahan per jenis CAPTCHA. Lihat daftar lengkap paket di halaman pricing captchaai.com.

Berapa batas ukuran file gambar grid?

Jaga gambar tetap di bawah 600KB. Jika muncul ERROR_TOO_BIG_CAPTCHA_FILESIZE, perkecil resolusi atau kompres ke PNG/JPEG sebelum mengirim ulang. Gambar yang terlalu besar ditolak sebelum diproses.

Bisakah metode grid menangani grid dinamis yang tile-nya berubah?

Tidak. Metode post menyelesaikan satu gambar statis. Untuk reCAPTCHA yang mengganti tile setelah diklik, gunakan metode token (method=userrecaptcha) yang menangani siklus tantangannya secara berbeda.


Panduan terkait

Komentar dinonaktifkan untuk artikel ini.