Use Cases

Автоматизация правительственного портала с помощью решения CAPTCHA

Портал BLS обрывает сессию через 5–10 минут, сайт DMV — через 15, налоговый портал — ещё быстрее. Если reCAPTCHA v2 или графическая CAPTCHA на входе не решается за пару секунд, форму приходится заполнять заново.

Ниже — рабочие сценарии на Python для BLS, судебных архивов, разрешений и публичных записей: вход, поиск дела и подача заявки через API CaptchaAI без потери сессии.


CAPTCHA на государственных порталах: где что встречается

  • Виза / иммиграция (BLS, reCAPTCHA v2) — порталы BLS, USCIS; сценарий: запись на приём.
  • DMV / транспортные средства (reCAPTCHA v2, изображение) — сайты DMV штатов; сценарий: продление регистрации.
  • Судебные архивы (reCAPTCHA v2) — PACER, суды штатов; сценарий: поиск дела.
  • Разрешения / лицензии (графическая CAPTCHA) — городские порталы разрешений; сценарий: подача заявки.
  • Налоговые порталы (reCAPTCHA v2) — IRS, налоговые сайты штатов; сценарий: проверка статуса подачи.
  • Публичные записи (графическая CAPTCHA, reCAPTCHA) — окружные архивы; сценарий: поиск по адресу/участку.

Тайм-ауты сессии: сколько времени есть на решение CAPTCHA

Прежде чем писать код, стоит понимать бюджет времени — он определяет, можно ли решать CAPTCHA синхронно или нужно готовить токен заранее.

  • Визовые порталы: тайм-аут 5–10 мин → проходите весь сценарий за один прогон, без пауз.
  • Сайты DMV: тайм-аут 15 мин → обновляйте cookie сессии на середине сценария.
  • Судебные архивы: тайм-аут 20–30 мин → группируйте поиски пакетами.
  • Налоговые порталы: тайм-аут 10–15 мин → используйте закреплённый (sticky) прокси с одним IP на весь сеанс.
  • Заявки на разрешения: тайм-аут 30 мин → сохраняйте прогресс после каждого шага формы.

Запись на визу через BLS: автоматизация с CAPTCHA

Порталы BLS International — основной канал записи на подачу документов на шенгенскую и другие визы для заявителей из России, Казахстана и других стран СНГ, и у них собственная реализация CAPTCHA.

CaptchaAI решает BLS CAPTCHA со стабильно высокой долей успешных решений — как для входа в личный кабинет, так и для самой записи на слот:

import requests
import time
import base64

CAPTCHAAI_KEY = "YOUR_API_KEY"
CAPTCHAAI_URL = "https://ocr.captchaai.com"


def solve_bls_captcha(captcha_image_url, session):
    """Solve BLS-specific CAPTCHA."""
    # Download CAPTCHA image
    img_resp = session.get(captcha_image_url)
    img_b64 = base64.b64encode(img_resp.content).decode()

    resp = requests.post(f"{CAPTCHAAI_URL}/in.php", data={
        "key": CAPTCHAAI_KEY,
        "method": "base64",
        "body": img_b64,
        "json": 1,
    })
    task_id = resp.json()["request"]

    for _ in range(30):
        time.sleep(3)
        result = requests.get(f"{CAPTCHAAI_URL}/res.php", params={
            "key": CAPTCHAAI_KEY, "action": "get",
            "id": task_id, "json": 1,
        })
        data = result.json()
        if data["request"] != "CAPCHA_NOT_READY":
            return data["request"]

    raise TimeoutError("BLS CAPTCHA timeout")


class BLSAppointmentBooker:
    def __init__(self):
        self.session = requests.Session()
        self.session.headers.update({
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
            "AppleWebKit/537.36 Chrome/126.0.0.0 Safari/537.36",
        })

    def login(self, portal_url, email, password):
        """Login to BLS portal with CAPTCHA."""
        resp = self.session.get(portal_url)

        # Extract CAPTCHA image URL from page
        import re
        match = re.search(r'src="(/captcha[^"]+)"', resp.text)
        if match:
            captcha_url = portal_url.rstrip("/") + match.group(1)
            captcha_text = solve_bls_captcha(captcha_url, self.session)
        else:
            captcha_text = ""

        login_resp = self.session.post(portal_url, data={
            "email": email,
            "password": password,
            "captcha": captcha_text,
        })
        return login_resp.status_code == 200

    def check_appointment_slots(self, slots_url):
        """Check available appointment slots."""
        resp = self.session.get(slots_url)
        if resp.status_code == 200:
            return resp.json().get("available_slots", [])
        return []

    def book_slot(self, booking_url, slot_id, applicant_data):
        """Book an appointment slot, handling any CAPTCHA."""
        resp = self.session.get(booking_url)

        # Check for CAPTCHA on booking page
        import re
        match = re.search(r'src="(/captcha[^"]+)"', resp.text)
        if match:
            captcha_url = booking_url.rstrip("/") + match.group(1)
            captcha_text = solve_bls_captcha(captcha_url, self.session)
        else:
            captcha_text = ""

        resp = self.session.post(booking_url, data={
            "slot_id": slot_id,
            "captcha": captcha_text,
            **applicant_data,
        })

        return {
            "success": resp.status_code == 200,
            "confirmation": resp.json().get("confirmation_number"),
        }

confirmation_number стоит логировать отдельно — это единственное доказательство брони, если сессия сразу оборвётся.


Поиск судебных дел без ручного ввода CAPTCHA

Судебные архивы вроде PACER и порталов штатов почти всегда прикрывают форму поиска обычной reCAPTCHA v2 — тот же токен, что и на большинстве коммерческих сайтов, поэтому логика решения не отличается от типового кейса.

def solve_recaptcha(sitekey, pageurl):
    resp = requests.post(f"{CAPTCHAAI_URL}/in.php", data={
        "key": CAPTCHAAI_KEY,
        "method": "userrecaptcha",
        "googlekey": sitekey,
        "pageurl": pageurl,
        "json": 1,
    })
    task_id = resp.json()["request"]

    for _ in range(60):
        time.sleep(5)
        result = requests.get(f"{CAPTCHAAI_URL}/res.php", params={
            "key": CAPTCHAAI_KEY, "action": "get",
            "id": task_id, "json": 1,
        })
        data = result.json()
        if data["request"] != "CAPCHA_NOT_READY":
            return data["request"]
    raise TimeoutError("Timeout")


class CourtRecordSearcher:
    def __init__(self, proxy=None):
        self.session = requests.Session()
        if proxy:
            self.session.proxies = {"http": proxy, "https": proxy}
        self.session.headers.update({
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
            "AppleWebKit/537.36 Chrome/126.0.0.0 Safari/537.36",
        })

    def search_cases(self, court_url, search_params, sitekey):
        """Search court records with reCAPTCHA handling."""
        # Load search page
        self.session.get(court_url)

        # Solve CAPTCHA
        token = solve_recaptcha(sitekey, court_url)

        # Submit search with token
        resp = self.session.post(court_url, data={
            **search_params,
            "g-recaptcha-response": token,
        })

        if resp.status_code == 200:
            return self._parse_results(resp.text)
        return []

    def _parse_results(self, html):
        from bs4 import BeautifulSoup
        soup = BeautifulSoup(html, "html.parser")
        cases = []
        for row in soup.select("table.results tr")[1:]:
            cols = row.select("td")
            if len(cols) >= 4:
                cases.append({
                    "case_number": cols[0].get_text(strip=True),
                    "parties": cols[1].get_text(strip=True),
                    "date": cols[2].get_text(strip=True),
                    "status": cols[3].get_text(strip=True),
                })
        return cases

Прокси в CourtRecordSearcher не случайно опционален: многие судебные архивы не блокируют по IP — добавляйте прокси только столкнувшись с блокировкой.


Графическая CAPTCHA на порталах разрешений и лицензий

Многие городские и окружные порталы до сих пор используют простую графическую CAPTCHA вместо reCAPTCHA.

Почему это проще, чем кажется

Такие CAPTCHA обычно короче и менее искажены, чем на крупных коммерческих сайтах — метод base64 решает их так же, как и любую другую графическую капчу:

def solve_image_captcha(image_url, session):
    """Solve image-based CAPTCHA common on local government sites."""
    img = session.get(image_url)
    img_b64 = base64.b64encode(img.content).decode()

    resp = requests.post(f"{CAPTCHAAI_URL}/in.php", data={
        "key": CAPTCHAAI_KEY,
        "method": "base64",
        "body": img_b64,
        "json": 1,
    })
    task_id = resp.json()["request"]

    for _ in range(20):
        time.sleep(3)
        result = requests.get(f"{CAPTCHAAI_URL}/res.php", params={
            "key": CAPTCHAAI_KEY, "action": "get",
            "id": task_id, "json": 1,
        })
        data = result.json()
        if data["request"] != "CAPCHA_NOT_READY":
            return data["request"]

    raise TimeoutError("Image CAPTCHA timeout")

Массовая проверка публичных записей

Перед пакетным сбором данных убедитесь, что вы вправе обрабатывать эти сведения по роду задачи — например, только собственные дела или заведомо общедоступные записи. Для российской аудитории это требование должной осмотрительности по 152-ФЗ «О персональных данных», для трансграничных проектов — аналогичная осмотрительность в духе GDPR.

import csv


def batch_property_lookup(addresses, portal_url, sitekey, output_file):
    """Look up multiple property records, solving CAPTCHA per batch."""
    session = requests.Session()
    session.headers.update({
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
        "AppleWebKit/537.36 Chrome/126.0.0.0 Safari/537.36",
    })

    results = []
    for i, address in enumerate(addresses):
        try:
            # Solve CAPTCHA every 5th request (or when required)
            if i % 5 == 0:
                token = solve_recaptcha(sitekey, portal_url)

            resp = session.post(portal_url, data={
                "address": address,
                "g-recaptcha-response": token,
            })

            if resp.status_code == 200:
                results.append({
                    "address": address,
                    "data": resp.json(),
                })

            time.sleep(3)  # Be respectful

        except Exception as e:
            results.append({"address": address, "error": str(e)})

    # Save results
    with open(output_file, "w", newline="") as f:
        writer = csv.DictWriter(f, fieldnames=["address", "data", "error"])
        writer.writeheader()
        writer.writerows(results)

    return results

Типичные сбои и как их избежать

  1. Изображение CAPTCHA не загружается — истёк cookie сессии. Начните сессию заново.
  2. «Сессия истекла» при отправке формы — решение заняло слишком много времени. Запрашивайте решение заранее либо используйте более быстрый тип CAPTCHA.
  3. Неверный ответ на CAPTCHA — искажённое изображение. Сообщите о плохом изображении через API.
  4. Портал блокирует автоматизацию — детект по IP/User-Agent. Используйте резидентный прокси и реальный User-Agent.
  5. Ошибка валидации формы после CAPTCHA — токен истёк на стороне сервера. Решайте CAPTCHA непосредственно перед отправкой.

Часто задаваемые вопросы

Законно ли автоматизировать работу с государственными порталами?

Автоматизация собственных форм и поиска дел обычно разрешена; QA-тестирование гражданских сервисов — распространённый легитимный сценарий. Перед стартом проверьте условия использования конкретного портала.

Сколько потоков нужно, чтобы проверять сразу несколько визовых центров BLS?

  • BASIC ($15/мес, 5 потоков) — хватает на 2–3 центра одновременно
  • STANDARD ($30/мес, 15 потоков) — до 8–10 центров
  • ADVANCE ($90/мес, 50 потоков) — широкий мониторинг по всей стране

Один поток CaptchaAI обрабатывает одну задачу CAPTCHA единовременно, поэтому закладывайте по потоку на каждый одновременный запрос слотов.

Что делать, если сессия портала истекает раньше решения CAPTCHA?

Сверьтесь с тайм-аутом портала (см. список выше) и запрашивайте решение заранее. Если разрыв случается, разделите логин и отправку формы: получите токен и сразу инициируйте запрос.

Поддерживает ли CaptchaAI CAPTCHA портала BLS?

Да, через параметр method=bls для прямого решения или method=base64, если капча приходит изображением. Оба варианта дают стабильно высокую долю успешных решений.

Какие данные можно собирать при автоматизации госпорталов?

Только те, которые вы вправе обрабатывать по роду задачи, — например, статус собственного дела или заведомо общедоступные записи.

Для российской аудитории это требования 152-ФЗ, для трансграничных проектов — осмотрительность в духе GDPR. Это не юридическая консультация.


Похожие материалы

Если вам нужны более узкие руководства по отдельным типам CAPTCHA, встречающимся на госпорталах:


Что дальше

Начните с базовой настройки, затем переходите к конкретным типам CAPTCHA:

  1. CaptchaAI Quickstart: ваше первое решение CAPTCHA за 5 минут
  2. Как решить reCAPTCHA v2 через API: пошаговое руководство
  3. Как решить Cloudflare Turnstile через API
  4. Как решить GeeTest v3 через API
Комментарии для этой статьи отключены.