Hướng Dẫn API

Tham số instructions và code trong BLS CAPTCHA API

BLS CAPTCHA gặp nhiều nhất trên các cổng đặt lịch hẹn visa, nơi agency dịch vụ visa và dev Việt Nam hay cần script kiểm thử booking. Hai tham số hay bị bỏ qua khi gửi task tới CaptchaAI là instructions (chỉ dẫn trích từ ảnh CAPTCHA) và code (mã định danh biến thể BLS) — thiếu một trong hai, kết quả dễ bị từ chối với thử thách mơ hồ. Bài này đi thẳng vào cách trích xuất, khi nào cần dùng, và luồng gửi task bằng Python.

Ba điều cần nhớ trước khi đọc tiếp:

  • instructions/code là tham số tùy chọn — chỉ thêm khi trang thực sự cung cấp, đừng gửi chuỗi rỗng.
  • sitekeypageurl luôn bắt buộc, kể cả khi hai tham số kia có mặt.
  • Trang tải động là nguyên nhân phổ biến nhất khiến sitekey trích xuất ra rỗng.

Bảng tham số API BLS CAPTCHA

Tham số Bắt buộc Kiểu dữ liệu Mô tả
method Chuỗi bls
sitekey Chuỗi Sitekey của trang
pageurl Chuỗi URL trang hiển thị CAPTCHA
instructions Không Chuỗi Chỉ dẫn trích từ ảnh CAPTCHA
code Không Chuỗi Mã biến thể BLS CAPTCHA
json Không Số nguyên 1 để nhận JSON

Bước 1: Trích xuất sitekey, instructions và code

Đọc sitekey từ DOM, kèm instructions hiển thị trên trang và code giấu trong page_source, trong một lần load:

# 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)

sitekey rỗng thường nghĩa là CAPTCHA tải động — xem bảng lỗi bên dưới.

Lưu ý: trích xuất sitekey, instructionscode trong cùng một lần load trang — nếu portal render lại DOM sau vài giây (thường gặp trên cổng BLS), code lấy được ở lần load trước có thể không còn khớp.


Bước 2: Gửi task BLS CAPTCHA tới CaptchaAI

Gửi task cơ bản bằng Python

Chỉ thêm instructions/code khi thực sự có giá trị, đừng gửi chuỗi rỗng:

# 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}")

BLS CAPTCHA thường giải xong dưới 1 giây với tỷ lệ giải thành công cao — vẫn giữ 10 giây chờ trước lần poll đầu.

Lưu ý: đừng rút ngắn thời gian chờ 10 giây dù tốc độ giải trung bình nhanh — hàng đợi có thể dồn ứ vào giờ cao điểm, và poll quá sớm chỉ tốn thêm request tới res.php.


instructions và code: khi nào cần dùng từng tham số

Cả hai tham số đều tùy chọn, nhưng phục vụ hai mục đích khác nhau và không phải lúc nào cũng cần cùng lúc.

instructions: khi nào cần và cách lấy

instructions cho CaptchaAI biết CAPTCHA đang yêu cầu gì. Chỉ thật sự cần khi chỉ dẫn nằm ở phần tử HTML riêng, không nhúng trong ảnh:

# 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

code: xác định biến thể BLS CAPTCHA

Một số triển khai BLS phân loại thử thách bằng mã riêng, giấu trong JS hoặc data-*:

# 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

code có thể đổi giữa các lần tải trang — gọi lại hàm này trước mỗi lần gửi task.


Bước 3: Ghép toàn bộ luồng bằng Selenium

Điền form, giải CAPTCHA rồi submit:

# 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

Chờ bằng WebDriverWait trước khi đọc data-sitekey — bỏ qua bước này là nguyên nhân phổ biến nhất khi trích xuất thất bại trên trang tải động.


Lỗi thường gặp và cách xử lý

Trước khi tra bảng, kiểm tra nhanh ba điều sau — chiếm phần lớn các ca lỗi thực tế:

  • Response in.phpstatus: 1 không, hay đã báo lỗi ngay từ bước gửi task?
  • sitekey trích xuất được có rỗng hoặc chứa khoảng trắng thừa không?
  • Trang có tải lại DOM bằng JS sau khi driver.get() trả về không (ảnh hưởng cả sitekey lẫn code)?
Vấn đề Nguyên nhân Cách xử lý
ERROR_BAD_PARAMETERS Thiếu sitekey/pageurl Kiểm tra đã trích xuất đúng chưa
Kết quả bị từ chối Chưa gửi instructions Thêm instructions cho thử thách mơ hồ
Sai loại CAPTCHA Không phải BLS CAPTCHA Kiểm tra có phải reCAPTCHA hay loại khác
Không tìm thấy sitekey Trang tải động Đợi phần tử CAPTCHA render xong

Ứng dụng thực tế: BLS CAPTCHA trên cổng hẹn visa

BLS CAPTCHA phổ biến nhất trên portal đặt lịch hẹn visa (BLS International và nhà thầu tương tự xử lý hồ sơ Schengen, UK cho công dân Việt Nam). Agency visa và đội QA outsourcing (FPT Software, VNG, startup TP.HCM/Hà Nội) thường kiểm thử luồng đặt lịch của chính mình trước khi giao khách hàng.

Các tác vụ QA thường gặp trên nhóm cổng này:

  • Xác nhận biểu mẫu và sitekey vẫn đúng sau mỗi lần cổng đổi giao diện.
  • Kiểm thử lại toàn bộ luồng đặt lịch sau một bản deploy mới của agency, trước khi giao cho khách hàng.
  • Theo dõi thời gian phản hồi của in.php/res.php trong pipeline CI, không giữ chỗ hàng loạt.

Ghi log dữ liệu người đặt lịch tối thiểu, theo Nghị định 13/2023/NĐ-CP.


Câu hỏi thường gặp

instructions có bắt buộc không?

Không, nhưng thử thách mơ hồ nên truyền để giảm tỷ lệ bị từ chối.

code đổi giữa các lần tải trang thì làm gì?

Trích xuất lại mỗi lần, đừng cache — code có thể đổi theo phiên hoặc IP.

Dùng BLS CAPTCHA tự động hóa QA cổng hẹn visa có ổn không?

Có, nếu kiểm thử trên luồng của chính mình — không giữ chỗ hàng loạt hay bán lại suất hẹn.

Không tìm thấy sitekey vì trang tải động thì sao?

Dùng WebDriverWait thay vì gọi find_element ngay sau driver.get().

Nên poll res.php trong bao lâu trước khi timeout?

Ví dụ trong bài dùng 30 lần poll cách nhau 5 giây, cộng 10 giây chờ ban đầu — tổng khoảng 160 giây. Với BLS CAPTCHA thời gian giải thực tế dưới 1 giây nên hiếm khi chạm ngưỡng này; nếu timeout thường xuyên, kiểm tra lại sitekey/pageurl trước khi tăng số lần poll.


Đọc thêm


Nắm vững tham số BLS CAPTCHA — bắt đầu với CaptchaAI.

Os comentários estão desativados para este artigo.