API Tutorials

如何逐步解决 BLS 验证码

BLS 国际签证预约系统会在提交表单前弹出一种九宫格图片验证码:页面给一句提示文字,比如“选出所有带汽车的图片”,你需要从多张图片里选出符合要求的几张。手动点几次没问题,但批量预约或自动化脚本遇到这种验证码,靠人工根本处理不过来。

完整流程:提取图片和指令 → 提交任务 → 轮询结果 → 点击图片提交,每步都给了 Python 和 Node.js 代码。


准备工作

  • CaptchaAI API Key —— 在 CaptchaAI 官网 注册后获取
  • BLS CAPTCHA 图片 —— 从页面提取,需转成 Base64 编码
  • 指令文字 —— 页面上说明该选哪些图片的文本
  • 运行环境 —— Python 3.7+ 或 Node.js 14+

第 1 步:提取页面上的图片和指令文字

BLS CAPTCHA 通常显示 3–9 张图片,配一句指令,例如“选出所有带汽车的图片”。

用 Selenium 提取

from selenium import webdriver
from selenium.webdriver.common.by import By
import base64
import requests as req

driver = webdriver.Chrome()
driver.get("https://blsitalypakistan.com/appointment")

# Get instruction text
instruction = driver.find_element(By.CSS_SELECTOR, ".captcha-instruction").text
print(f"Instruction: {instruction}")

# Get all captcha images as base64
images = {}
captcha_imgs = driver.find_elements(By.CSS_SELECTOR, ".captcha-image img")
for i, img in enumerate(captcha_imgs, 1):
    src = img.get_attribute("src")
    if src.startswith("data:image"):
        # Already base64
        images[f"image_base64_{i}"] = src.split(",")[1]
    else:
        # Download and encode
        img_data = req.get(src).content
        images[f"image_base64_{i}"] = base64.b64encode(img_data).decode()

用 Puppeteer 提取

const puppeteer = require('puppeteer');

const browser = await puppeteer.launch({ headless: 'new' });
const page = await browser.newPage();
await page.goto('https://blsitalypakistan.com/appointment');

// Get instruction
const instruction = await page.$eval('.captcha-instruction', el => el.textContent);

// Get images as base64
const images = await page.$$eval('.captcha-image img', imgs =>
  imgs.map((img, i) => ({
    key: `image_base64_${i + 1}`,
    value: img.src.startsWith('data:') ? img.src.split(',')[1] : null
  }))
);

第 2 步:把图片和指令提交给 CaptchaAI

把指令文字和所有图片一起发给 BLS 求解器。

Python

import requests
import time

API_KEY = "YOUR_API_KEY"

payload = {
    "key": API_KEY,
    "method": "bls",
    "instructions": instruction,
    "json": 1
}

# Add each image (up to 9)
for key, value in images.items():
    payload[key] = value

response = requests.post("https://ocr.captchaai.com/in.php", data=payload)
data = response.json()

if data.get("status") != 1:
    raise Exception(f"Submit error: {data.get('request')}")

task_id = data["request"]
print(f"Task submitted: {task_id}")

Node.js

const axios = require('axios');
const FormData = require('form-data');

async function submitBLS(instruction, images) {
  const params = {
    key: 'YOUR_API_KEY',
    method: 'bls',
    instructions: instruction,
    json: 1,
    ...Object.fromEntries(images.map(img => [img.key, img.value]))
  };

  const { data } = await axios.post('https://ocr.captchaai.com/in.php', null, { params });
  if (data.status !== 1) throw new Error(data.request);
  return data.request;
}

第 3 步:轮询获取识别结果

识别结果会返回正确图片的编号。

Python

def get_bls_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"]  # e.g., "1,3,5" (image indices)
        if result.get("request") != "CAPCHA_NOT_READY":
            raise Exception(f"Error: {result.get('request')}")

    raise Exception("Timeout")

solution = get_bls_solution(task_id)
print(f"Select images: {solution}")  # e.g., "1,3,5"

第 4 步:点击正确图片并提交表单

拿到编号后,在页面上依次点击对应的图片:

# Parse the solution indices
selected = [int(i) for i in solution.split(",")]

# Click each correct image
captcha_imgs = driver.find_elements(By.CSS_SELECTOR, ".captcha-image img")
for idx in selected:
    captcha_imgs[idx - 1].click()  # Convert 1-based to 0-based
    time.sleep(0.3)  # Small delay between clicks

# Submit the form
driver.find_element(By.CSS_SELECTOR, ".captcha-submit").click()

完整代码示例(Python)

把前面 4 步串成一份可以直接运行的脚本。

import requests
import time
import base64
from selenium import webdriver
from selenium.webdriver.common.by import By

API_KEY = "YOUR_API_KEY"
driver = webdriver.Chrome()
driver.get("https://blsitalypakistan.com/appointment")

# 1. Extract instruction and images
instruction = driver.find_element(By.CSS_SELECTOR, ".captcha-instruction").text
captcha_imgs = driver.find_elements(By.CSS_SELECTOR, ".captcha-image img")

payload = {"key": API_KEY, "method": "bls", "instructions": instruction, "json": 1}
for i, img in enumerate(captcha_imgs, 1):
    src = img.get_attribute("src")
    if src.startswith("data:image"):
        payload[f"image_base64_{i}"] = src.split(",")[1]

# 2. Submit to CaptchaAI
resp = requests.post("https://ocr.captchaai.com/in.php", data=payload).json()
task_id = resp["request"]

# 3. Poll for solution
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:
        selected = [int(i) for i in result["request"].split(",")]
        break

# 4. Click correct images and submit
for idx in selected:
    captcha_imgs[idx - 1].click()
    time.sleep(0.3)
driver.find_element(By.CSS_SELECTOR, ".captcha-submit").click()

print("CAPTCHA solved!")
driver.quit()

常见错误与处理方式

  • ERROR_BAD_PARAMETERS(缺少指令文字或图片)—— 确保同时提交了文字说明和至少一张图片
  • ERROR_CAPTCHA_UNSOLVABLE(图片太模糊或无法识别)—— 提高截图质量,检查 Base64 编码是否正确
  • 选错了图片(图片编号顺序不对)—— 确认图片编号和页面显示顺序完全一致
  • 提交后被拒绝(提取图片后页面内容已经刷新)—— 提取完立即提交,不要中间等待或做其他操作

国内网络环境下装依赖慢,可以用清华 TUNA 镜像:pip install -i https://pypi.tuna.tsinghua.edu.cn/simple selenium requests


常见问题

BLS CAPTCHA 一般显示几张图片?

通常是 3 到 9 张,数量因页面和会话而异。脚本里不要写死张数,按实际抓取到的数量动态处理。

除了 Python 和 Node.js,还支持哪些语言?

支持。BLS 求解器同样兼容 PHP、Go、Java、C#、Ruby、Rust、Kotlin 和 Bash,接口逻辑一致,换个语言发 HTTP 请求即可。

识别一次 BLS CAPTCHA 大概要多久?

一般 15–30 秒。图片类验证码比纯文本验证码耗时更长,轮询间隔建议设在 5 秒左右。

指令文字必须是英文吗?

不需要。instructions 是纯文本字段,把页面上抓取到的原始文字直接传过去即可,无需翻译。


需要完整可运行的项目?

想要包含环境配置、重试和错误处理的完整项目?

点击查看 GitHub 上的完整示例 →


相关指南

该文章已禁用评论。