API Tutorials

BLS CAPTCHA Görüntü Sıralaması ve Izgara Yanıtını İşleme

Kısa cevap: BLS ızgara CAPTCHA'sını çözmek kolay kısım — asıl risk, API'den dönen indeksleri ya da bitmask'i formun beklediğinden farklı göndermek. Format uyuşmazlığında form genelde sessizce reddeder, ayrı bir hata mesajı vermez; bu yüzden ızgara türünü ve yanıt biçimini göndermeden önce doğru eşlemek kritik. Bu rehberde üç ızgara türünü, hücre indekslemeyi, API çağrısını ve Selenium ile doğru gönderimi sırayla görüyorsunuz.

BLS vize randevu portalları gibi Schengen başvuru sistemlerinde bu ızgara CAPTCHA'ları sık görülür; QA ekipleri yetkili test akışlarında yanıt formatını doğru eşlemek zorundadır. Kişisel veri içeren formlarda KVKK kurallarını göz önünde bulundurun, testleri yalnızca yetkili ortamlarda çalıştırın.


BLS Izgara CAPTCHA Türleri

BLS ızgaraları üç farklı mantıkla çalışır; API çağrısı hepsinde aynı kalır, yalnızca instructions parametresiyle ilettiğiniz görünen talimat metni değişir. Hangi tür geldiğini önceden bilemeyeceğiniz için akışınızı üçünü de aynı fonksiyonla işleyecek şekilde kurmanız önerilir:

Tür Ne yapılır Örnek talimat
Görüntü Sıralaması Görüntüler belirli bir mantıkla (artan sayı, alfabetik sıra) doğru sıraya dizilir "Görüntüleri küçükten büyüğe sıralayın"
Görüntü Seçimi Verilen açıklamayla eşleşen görüntüler işaretlenir "İçinde metin geçen tüm görüntüleri seçin"
Desen Eşleştirme Örnek desenle eşleşen görüntüler belirlenir "Sol üstteki örnekle eşleşen görüntüyü seçin"

Izgara Düzeni ve Hücre İndeksleri

BLS ızgaraları genellikle 3x3 veya 4x4 düzeninde gelir; her hücre API yanıtında düz bir indekse karşılık gelir. Sıralama ya da seçim öncesi bu eşlemeyi doğru kurun:

  • 3x3 ızgara: 9 hücre, indeksler 08 arasında; satır/sütun dönüşümü cols=3 ile yapılır.
  • 4x4 ızgara: 16 hücre, indeksler 015 arasında; satır/sütun dönüşümü cols=4 ile yapılır.
  • grid_position() ve index_from_position() bu dönüşümü iki yönde de sağlar — Selenium'da hücre bulurken ikisi de gerekir.
# grid_mapping.py

# BLS grids typically use 3x3 or 4x4 layouts
# Each cell maps to an index:

# 3x3 grid:
# [0] [1] [2]
# [3] [4] [5]
# [6] [7] [8]

# 4x4 grid:
#  [0]  [1]  [2]  [3]
#  [4]  [5]  [6]  [7]
#  [8]  [9] [10] [11]
# [12] [13] [14] [15]

def grid_position(index, cols=3):
    """Convert flat index to row, column."""
    return index // cols, index % cols


def index_from_position(row, col, cols=3):
    """Convert row, column to flat index."""
    return row * cols + col


# Example: For a 3x3 grid, position (1, 2) = index 5
print(grid_position(5, cols=3))   # (1, 2)
print(index_from_position(1, 2))  # 5

BLS Izgara CAPTCHA'sını API ile Çözme

sitekey ve pageurl değerlerini CaptchaAI'nin bls metoduna gönderin; API ızgara analizini kendi tarafında yapar ve hücre indekslerini döndürür. Üç parametre şöyle ayrılır:

  • sitekey: BLS ızgarasının site anahtarı; sayfanın CAPTCHA elemanından okunur.
  • pageurl: ızgaranın göründüğü tam sayfa URL'si.
  • instructions: opsiyonel ama önerilir — görünen talimat metnini ilettiğinizde çözüm doğruluğu artar.
# solve_bls_grid.py
import requests
import time
import os
import json


def solve_bls_grid(sitekey, pageurl, instructions=None):
    """Solve a BLS grid CAPTCHA and get response indices."""
    api_key = os.environ["CAPTCHAAI_API_KEY"]

    payload = {
        "key": api_key,
        "method": "bls",
        "sitekey": sitekey,
        "pageurl": pageurl,
        "json": 1,
    }
    if instructions:
        payload["instructions"] = instructions

    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"]

    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 grid solve timeout")

API Yanıtını Ayrıştırma ve Formatlama

Yanıt üç farklı biçimde gelebilir:

  • JSON dizisi: [1, 4, 7] gibi doğrudan ayrıştırılabilir bir liste.
  • Virgülle ayrılmış indeksler: "1,4,7"split(",") ile ayrıştırılır.
  • Tek değer: tek hücreli yanıtlarda ham değer.

Hedef site indeks yerine bitmask beklediğinde format_for_submission() dönüşümünü kullanın:

# parse_response.py
import json


def parse_grid_response(solution):
    """Parse CaptchaAI BLS response into actionable grid data."""
    # Solution may be JSON or comma-separated indices
    if isinstance(solution, str):
        try:
            parsed = json.loads(solution)
            return parsed
        except json.JSONDecodeError:
            pass

        # Try comma-separated indices
        if "," in solution:
            return [int(x.strip()) for x in solution.split(",")]

        # Single value
        return [solution]

    return solution


def format_for_submission(indices, grid_size=9):
    """Format indices for form submission."""
    # Some sites expect a bitmask
    bitmask = ["0"] * grid_size
    for idx in indices:
        if isinstance(idx, int) and 0 <= idx < grid_size:
            bitmask[idx] = "1"

    return {
        "indices": indices,
        "bitmask": "".join(bitmask),
        "count": len(indices),
    }

Selenium ile Çözümü Sayfaya Uygulama

Ayrıştırılmış indeksleri iki şekilde iletebilirsiniz:

  • Tıklama tabanlı: ızgara hücrelerine sırayla tıklayın (click_grid_cells() / set_order_sequence()).
  • Gizli input tabanlı: çözümü inject_hidden_response() ile forma doğrudan yazın.

Tıklamalar arasına kısa gecikme koyun; aksi halde site art arda gelen tıklamaları reddedebilir:

# inject_grid.py
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import time


def click_grid_cells(driver, indices):
    """Click specific grid cells based on solution indices."""
    wait = WebDriverWait(driver, 10)

    # Find all grid cells
    cells = wait.until(
        EC.presence_of_all_elements_located(
            (By.CSS_SELECTOR, ".captcha-grid .cell, .bls-grid img, .grid-item")
        )
    )

    for idx in indices:
        if isinstance(idx, int) and idx < len(cells):
            cells[idx].click()
            time.sleep(0.3)  # Brief delay between clicks


def set_order_sequence(driver, ordered_indices):
    """Click grid cells in the correct order for ordering challenges."""
    wait = WebDriverWait(driver, 10)

    cells = wait.until(
        EC.presence_of_all_elements_located(
            (By.CSS_SELECTOR, ".captcha-grid .cell, .bls-grid img")
        )
    )

    for idx in ordered_indices:
        if isinstance(idx, int) and idx < len(cells):
            cells[idx].click()
            time.sleep(0.5)  # Ordering needs pauses between clicks


def inject_hidden_response(driver, solution_value):
    """Set the solution in a hidden input field."""
    driver.execute_script("""
        var inputs = document.querySelectorAll(
            'input[name*="captcha"], input[name*="response"], #captcha-answer'
        );
        for (var i = 0; i < inputs.length; i++) {
            inputs[i].value = arguments[0];
        }
    """, str(solution_value))

Uçtan Uca BLS Izgara Akışı

Yukarıdaki fonksiyonları birleştirdiğinizde BLS ızgara CAPTCHA'sının uçtan uca otomatik işlenmesi böyle görünür: sitekey'i okuyun, CaptchaAI ile çözün, yanıtı doğru formata çevirin ve formu gönderin. handle_bls_grid() fonksiyonu hem tıklama tabanlı hem gizli input tabanlı ızgaraları aynı akışta ele alır, böylece BLS'nin sayfa yapısını her seferinde ayrıca kontrol etmenize gerek kalmaz.

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


def handle_bls_grid(driver, pageurl):
    """Complete BLS grid CAPTCHA handling."""

    wait = WebDriverWait(driver, 15)

    # Wait for CAPTCHA to load
    captcha = wait.until(
        EC.presence_of_element_located(
            (By.CSS_SELECTOR, "[data-sitekey], .bls-captcha")
        )
    )
    sitekey = captcha.get_attribute("data-sitekey")

    # Get instructions
    instructions = None
    try:
        inst = driver.find_element(By.CSS_SELECTOR, ".captcha-instructions")
        instructions = inst.text.strip()
    except Exception:
        pass

    # Solve via CaptchaAI
    solution = solve_bls_grid(sitekey, pageurl, instructions)
    parsed = parse_grid_response(solution)

    # Determine response method
    grid_cells = driver.find_elements(
        By.CSS_SELECTOR, ".captcha-grid .cell, .bls-grid img"
    )

    if grid_cells:
        # Click-based response
        if isinstance(parsed, list) and all(isinstance(x, int) for x in parsed):
            click_grid_cells(driver, parsed)
        else:
            inject_hidden_response(driver, solution)
    else:
        # Hidden input response
        inject_hidden_response(driver, solution)

    # Submit
    submit = driver.find_element(
        By.CSS_SELECTOR, "button[type='submit'], .submit-btn, #verify"
    )
    submit.click()

    return True

Sorun Giderme

Aşağıdaki tabloda en sık karşılaşılan seçici, zamanlama ve format sorunlarını, olası sebepleriyle birlikte bulabilirsiniz:

Sorun Sebep Çözüm
Yanlış hücreler tıklanıyor Seçici (selector) uyuşmuyor Izgara HTML'sini inceleyip CSS seçicilerini güncelleyin
Sıralama reddediliyor Tıklamalar çok hızlı Tıklamalar arasına 300–500 ms gecikme koyun
Çözüm formatı uyuşmuyor Site bitmask bekliyor, indeks geldi format_for_submission() ile dönüştürün
Izgara tam yüklenmeden çözülüyor Görüntüler yavaş yükleniyor Çözmeden önce tüm görüntülerin yüklenmesini bekleyin
İstek zaman aşımına uğruyor res.php sorgulama süresi standart aralığı aşıyor Bekleme aralığını uzatın, ağ gecikmesini kontrol edin

Sık Sorulan Sorular

BLS ızgara CAPTCHA'sı ne kadar sürede çözülür?

Tipik olarak 1 saniyenin altında, yüksek başarı oranıyla — darboğaz genelde yanıtı forma doğru aktarmaktır.

Desen eşleştirme ızgaraları farklı mı işlenir?

Hayır. Üç ızgara türü de aynı bls metoduyla çözülür; yalnızca instructions parametresiyle ilettiğiniz talimat metni değişir.

Gönderim sonrası ikinci bir ızgara çıkarsa ne yapmalıyım?

Bazı BLS formları ilk ızgara geçtikten sonra ikinci bir CAPTCHA gösterir. Gönderim sonrası yeni .bls-captcha öğesi var mı kontrol edin; varsa akışı tekrar çalıştırın.

Aynı ızgara çözümünü tekrar kullanabilir miyim?

Hayır. Her çözüm o anki sorgulama oturumuna bağlıdır; her denemede API'den taze bir çözüm alın.

BLS ızgara işleri için hangi CaptchaAI planı yeterli?

Düşük-orta hacimli test akışları için BASIC ($15/ay, 5 thread) genellikle yeterlidir; ayrı bir "ızgara" ücreti yoktur. QA test hacmini paralel olarak artırmak istediğinizde daha yüksek thread sayısına sahip bir üst plana geçmeniz yeterli, entegrasyon kodunuzda değişiklik gerekmez.


İlgili Kılavuzlar

Parametre isimleri ve olası hata kodları için BLS CAPTCHA parametreleri rehberine göz atın; instructions alanının nasıl biçimlendirileceği de orada ayrıntılı anlatılıyor. GeeTest ile kıyaslamak isterseniz GeeTest ve BLS karşılaştırmasını inceleyin — iki tür arasında ızgara mantığı farklıdır.


BLS ızgara CAPTCHA'larını API ile birkaç dakikada otomatikleştirin — CaptchaAI ile başlayın.

Bu makale için yorumlar devre dışı bırakılmıştır.