Dua parameter membedakan BLS CAPTCHA dari tipe lain di API CaptchaAI: instructions dan code. Keduanya bersifat opsional, tetapi salah menaruh atau melewatkannya adalah penyebab paling sering solusi Anda ditolak. Panduan ini memetakan setiap field pada method bls, cara mengambilnya dari halaman, lalu cara mengirimnya ke in.php dan menariknya kembali lewat res.php supaya hasilnya konsisten.
BLS CAPTCHA adalah tantangan berbasis urutan gambar yang sering muncul di portal appointment dan formulir bertahap. Untuk tim otomasi dan QA di Indonesia yang terbiasa menguji alur form seperti ini, kabar baiknya: setelah keempat parameter inti benar, sisa integrasinya identik dengan tipe CAPTCHA lain di CaptchaAI — kirim task, simpan ID, polling, pakai token.
Parameter BLS CAPTCHA yang perlu Anda kirim
Method bls menerima tiga parameter wajib dan tiga opsional. sitekey, pageurl, dan method tidak bisa ditawar; instructions, code, dan json menentukan akurasi serta format respons.
| Parameter | Diperlukan | Tipe | Deskripsi |
|---|---|---|---|
method |
Ya | string | Harus bls |
sitekey |
Ya | string | Kunci BLS CAPTCHA situs |
pageurl |
Ya | string | URL halaman yang menampilkan CAPTCHA |
instructions |
Tidak | string | Instruksi teks dari gambar CAPTCHA |
code |
Tidak | string | Kode BLS CAPTCHA/pengidentifikasi tipe |
json |
Tidak | integer | Setel ke 1 untuk respons JSON |
Selalu kirim json=1. Tanpa itu API membalas string mentah, dan parsing status/request jadi lebih rapuh.
Cara mengekstrak sitekey dan parameter dari halaman
Langkah pertama selalu sama: baca sitekey dari DOM sebelum menyentuh API. BLS CAPTCHA umumnya menyimpan kunci di atribut data-sitekey, sementara teks instruksi berada di elemen terpisah yang kadang baru dirender setelah halaman aktif.
# extract_bls.py
import re
from selenium import webdriver
from selenium.webdriver.common.by import By
def extract_bls_params(url):
"""Extract BLS CAPTCHA parameters from a page."""
driver = webdriver.Chrome()
driver.get(url)
params = {"pageurl": url}
# Extract sitekey
captcha_el = driver.find_element(By.CSS_SELECTOR, "[data-sitekey], .bls-captcha")
sitekey = captcha_el.get_attribute("data-sitekey")
if sitekey:
params["sitekey"] = sitekey
# Extract instructions if visible
try:
instructions_el = driver.find_element(
By.CSS_SELECTOR, ".captcha-instructions, .captcha-text"
)
params["instructions"] = instructions_el.text.strip()
except Exception:
pass
# Extract code from hidden input or script
page_source = driver.page_source
code_match = re.search(r'captcha_code["\']?\s*[:=]\s*["\']([^"\']+)', page_source)
if code_match:
params["code"] = code_match.group(1)
driver.quit()
return params
# Usage
params = extract_bls_params("https://bls-example.com/appointment")
print(params)
Fungsi ini mengembalikan dictionary yang langsung bisa dipakai sebagai payload. Perhatikan pola try/except pada instructions: parameter opsional tidak boleh membuat ekstraksi gagal total — bila teks tidak ada, alur tetap lanjut tanpanya.
Mengirim BLS CAPTCHA ke API CaptchaAI
Pola submit dan polling
Setelah parameter terkumpul, kirim task ke in.php, simpan task ID dari respons, lalu polling res.php sampai statusnya 1. Selama solusi belum siap, API membalas CAPCHA_NOT_READY — perlakukan itu sebagai sinyal "tunggu", bukan error.
# solve_bls_basic.py
import requests
import time
import os
def solve_bls(sitekey, pageurl, instructions=None, code=None):
"""Solve BLS CAPTCHA via CaptchaAI API."""
api_key = os.environ["CAPTCHAAI_API_KEY"]
payload = {
"key": api_key,
"method": "bls",
"sitekey": sitekey,
"pageurl": pageurl,
"json": 1,
}
# Add optional parameters for higher accuracy
if instructions:
payload["instructions"] = instructions
if code:
payload["code"] = code
resp = requests.post(
"https://ocr.captchaai.com/in.php",
data=payload,
timeout=30,
)
result = resp.json()
if result.get("status") != 1:
raise RuntimeError(f"Submit failed: {result.get('request')}")
task_id = result["request"]
# Poll for result
time.sleep(10)
for _ in range(30):
resp = requests.get("https://ocr.captchaai.com/res.php", params={
"key": api_key,
"action": "get",
"id": task_id,
"json": 1,
}, timeout=15)
data = resp.json()
if data.get("status") == 1:
return data["request"]
if data["request"] != "CAPCHA_NOT_READY":
raise RuntimeError(data["request"])
time.sleep(5)
raise TimeoutError("BLS solve timeout")
# Usage
solution = solve_bls(
sitekey="your-bls-sitekey",
pageurl="https://bls-example.com/appointment",
instructions="Select images in the correct order",
)
print(f"Solution: {solution}")
Model penagihan CaptchaAI berbasis thread, bukan per solve, jadi loop polling ini tidak menambah biaya per percobaan. Satu paket BASIC ($15/bulan, 5 thread) sudah menampung lima BLS CAPTCHA berjalan bersamaan dengan solve tak terbatas per thread — cukup untuk sebagian besar suite QA. Kalau Anda deploy worker di ap-southeast-1 (Singapura) atau ap-southeast-3 (Jakarta), latensi jaringan ke API relatif kecil sehingga jeda polling bisa Anda pertahankan tetap pendek.
Kapan parameter instructions berpengaruh
Parameter instructions memberi tahu CaptchaAI apa yang sebenarnya diminta CAPTCHA. Ini paling berguna ketika teks tantangan tidak menyatu di dalam gambar, misalnya perintah "susun sesuai urutan" yang tampil di elemen HTML terpisah. Kirimkan teks itu apa adanya dalam bahasa Inggris — jangan diterjemahkan, karena model dilatih pada frasa aslinya.
# Common BLS instruction patterns:
instructions_examples = [
"Select images in the correct order",
"Click the images in order from left to right",
"Arrange the images by number",
"Select the matching image",
"Click in the order shown",
]
# Extract instructions from the CAPTCHA image area
def get_instructions_from_page(driver):
"""Try multiple selectors to find instruction text."""
selectors = [
".captcha-instructions",
".bls-captcha-text",
"#captcha-prompt",
".challenge-text",
]
for sel in selectors:
try:
el = driver.find_element(By.CSS_SELECTOR, sel)
text = el.text.strip()
if text:
return text
except Exception:
continue
return None
Fungsi get_instructions_from_page mencoba beberapa selector berurutan karena tata letak BLS berbeda antar penerbit. Selama satu selector menghasilkan teks, sisanya dilewati.
Peran parameter code pada varian BLS
Parameter code menandai varian BLS CAPTCHA. Sebagian implementasi memakai beberapa jenis tantangan yang dibedakan oleh sebuah kode, dan mengirim kode yang tepat membantu API memilih penanganan yang sesuai.
# Detect BLS CAPTCHA code from page
def detect_bls_code(page_source):
"""Detect which BLS CAPTCHA code/type is being used."""
patterns = [
(r'captchaType["\']?\s*[:=]\s*["\'](\w+)', "captchaType"),
(r'data-captcha-code["\']?\s*=\s*["\'](\w+)', "data attribute"),
(r'bls_code["\']?\s*[:=]\s*["\'](\w+)', "bls_code"),
]
for pattern, source in patterns:
match = re.search(pattern, page_source)
if match:
return match.group(1)
return None
Karena nilai code bisa berpindah antar sesi, ekstrak ulang setiap kali alih-alih menyimpannya sebagai konstanta. Menghardcode kode lama adalah jebakan klasik yang membuat solusi tiba-tiba ditolak setelah situs memperbarui varian tantangannya.
Alur BLS end-to-end dengan Selenium
Contoh berikut menyatukan semuanya: mengisi field form, mengekstrak sitekey dan instructions, memanggil solve_bls, menyuntikkan token ke DOM, lalu submit form. Ini pola yang sama yang Anda pakai untuk memverifikasi form Anda sendiri di lingkungan staging.
# full_bls_flow.py
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
import os
import re
def solve_bls_with_selenium(url, form_data=None):
"""Complete BLS CAPTCHA flow using Selenium."""
driver = webdriver.Chrome()
driver.get(url)
wait = WebDriverWait(driver, 15)
# Fill any form fields before CAPTCHA
if form_data:
for field_id, value in form_data.items():
el = wait.until(EC.presence_of_element_located((By.ID, field_id)))
el.clear()
el.send_keys(value)
# Extract CAPTCHA parameters
captcha_container = wait.until(
EC.presence_of_element_located((By.CSS_SELECTOR, "[data-sitekey], .bls-captcha"))
)
sitekey = captcha_container.get_attribute("data-sitekey")
# Get instructions
instructions = None
try:
inst_el = driver.find_element(By.CSS_SELECTOR, ".captcha-instructions")
instructions = inst_el.text.strip()
except Exception:
pass
# Solve via API
solution = solve_bls(
sitekey=sitekey,
pageurl=driver.current_url,
instructions=instructions,
)
# Inject solution
driver.execute_script("""
var input = document.querySelector('input[name="captcha-response"], #captcha-response');
if (input) {
input.value = arguments[0];
} else {
var hidden = document.createElement('input');
hidden.type = 'hidden';
hidden.name = 'captcha-response';
hidden.value = arguments[0];
document.forms[0].appendChild(hidden);
}
""", solution)
# Submit form
submit_btn = driver.find_element(By.CSS_SELECTOR, "button[type='submit'], #submit")
submit_btn.click()
# Wait for confirmation
wait.until(EC.url_changes(url))
result_url = driver.current_url
driver.quit()
return result_url
Perhatikan bahwa pageurl diambil dari driver.current_url, bukan URL awal — ini penting bila halaman melakukan redirect sebelum CAPTCHA muncul. Untuk pekerjaan scraping, batasi diri pada data yang memang berhak Anda proses; UU Pelindungan Data Pribadi (UU 27/2022) menempatkan data pribadi di luar cakupan pengambilan tanpa dasar yang sah.
Mengatasi error yang umum muncul
Sebagian besar kegagalan BLS berpangkal pada parameter yang salah ekstrak, bukan pada API. Tabel ini merangkum yang paling sering ditemui.
| Masalah | Penyebab | Solusi |
|---|---|---|
ERROR_BAD_PARAMETERS |
sitekey atau pageurl tidak ada |
Pastikan keduanya diekstraksi dengan benar |
| Solusi ditolak | Instruksi tidak disertakan | Sertakan parameter instructions untuk tantangan yang ambigu |
| Tipe CAPTCHA salah | Bukan BLS CAPTCHA | Periksa apakah itu benar-benar reCAPTCHA atau tipe khusus |
sitekey tidak ditemukan |
Pemuatan dinamis | Tunggu hingga elemen CAPTCHA dirender sebelum mengekstraksi |
Pertanyaan umum
Apa bedanya parameter instructions dan code?
instructions mendeskripsikan isi tantangan ("susun gambar sesuai urutan"), sedangkan code menandai varian teknis BLS yang dipakai situs. Keduanya opsional, tetapi mengisi keduanya menaikkan akurasi pada tantangan yang ambigu.
Apakah parameter code harus diekstrak ulang setiap sesi?
Ya. Nilai code bisa berubah berdasarkan sesi atau lokasi geografis, jadi baca ulang dari halaman setiap kali dan jangan menyimpannya sebagai konstanta.
Berapa lama penyelesaian BLS CAPTCHA?
CAPTCHA-nya sendiri termasuk yang respons kompetitif: SLA CaptchaAI untuk BLS berada di bawah 1 detik dengan tingkat keberhasilan tinggi pada tipe yang didukung. Waktu wall-clock yang Anda lihat sebagian besar berasal dari jeda polling di kode, bukan dari solve-nya.
Berapa thread yang saya perlukan untuk BLS?
Satu thread menangani satu BLS CAPTCHA in-flight. Untuk pengujian berkala, paket BASIC ($15/bulan, 5 thread) sudah memadai; naikkan ke STANDARD ($30/bulan, 15 thread) bila alur QA berjalan paralel dalam volume lebih besar.
Bagaimana jika situs juga memakai hCaptcha atau GeeTest v4?
Keduanya di luar cakupan: hCaptcha dan FunCaptcha tidak didukung, sedangkan GeeTest v4 masih berstatus segera hadir. Untuk situs semacam itu Anda perlu pendekatan lain — tetapi reCAPTCHA v2/v3, Turnstile, GeeTest v3, dan BLS sendiri didukung penuh.
Bacaan lanjutan
- Menangani urutan gambar dan respons grid BLS CAPTCHA
- Panduan langkah demi langkah menyelesaikan BLS CAPTCHA
Kuasai parameter BLS CAPTCHA — mulai dengan CaptchaAI.