Use Cases

Automação de portais governamentais com solução CAPTCHA

Cada portal público resolve CAPTCHA à sua maneira: o BLS tem um desafio próprio, DMVs e tribunais dos Estados Unidos preferem reCAPTCHA v2, e prefeituras e cartórios ainda usam CAPTCHA de imagem simples. Para quem faz QA de tecnologia cívica, consulta processual ou agendamento de visto para clientes brasileiros e portugueses em agências de viagem e escritórios de imigração, tratar cada tipo de portal separadamente é o que evita que o fluxo trave no meio do caminho.

Resposta rápida: identifique o portal antes de programar — BLS usa method=bls, reCAPTCHA v2 usa userrecaptcha, e a maioria dos alvarás roda CAPTCHA de imagem simples via method=base64.


Onde o CAPTCHA aparece: mapa por tipo de portal

  • Visto/imigração — BLS, reCAPTCHA v2 (portais BLS, USCIS): agendamento de consulta
  • DMV/veículos — reCAPTCHA v2, imagem (sites estaduais de DMV): renovação de registro
  • Registros judiciais — reCAPTCHA v2 (PACER, tribunais estaduais): consulta de processo
  • Alvarás/licenças — CAPTCHA de imagem (portais municipais): protocolo de requerimento
  • Portais fiscais — reCAPTCHA v2 (IRS, sites fiscais estaduais): consulta de status
  • Registros públicos — CAPTCHA de imagem, reCAPTCHA (cartórios): consulta de escritura

Sessões curtas: planeje antes de automatizar

Portais públicos expiram a sessão mais rápido que uma aplicação comercial — planeje o fluxo antes de pensar em CAPTCHA:

Tipo de portal Tempo de sessão O que fazer
Portais de visto 5-10 minutos Complete o fluxo em uma única passada
Sites de DMV 15 minutos Renove o cookie de sessão na metade do caminho
Registros judiciais 20-30 minutos Agrupe as consultas em lotes
Portais fiscais 10-15 minutos Use o mesmo egress de rede autorizado do início ao fim
Requerimento de alvará 30 minutos Salve o progresso a cada etapa do formulário

Automação fora dos EUA — por exemplo, workers em sa-east-1 da AWS — soma RTT extra; meça a latência antes de fixar esses tempos.


Agendamento de visto no portal BLS

O BLS International agenda vistos para consulados de vários países ao redor do mundo, cenário comum para agências que atendem clientes brasileiros e portugueses. O portal usa um CAPTCHA próprio; a CaptchaAI resolve com method=bls (direto) ou method=base64 (a partir da imagem).

Login, consulta de horários e agendamento

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

Consulta de processos e registros judiciais

Tribunais como o PACER protegem a busca de processos com reCAPTCHA v2.

Busca, resolução do token e parsing dos resultados

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

CAPTCHA de imagem em portais de alvará e licenciamento

Prefeituras raramente usam anti-bot sofisticado — a maioria tem CAPTCHA de imagem simples, o mais rápido de resolver da lista.

Função de resolução

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

Consulta em lote de registros públicos e imóveis

Cartórios costumam exigir CAPTCHA só a cada N requisições, não em toda consulta.

Consulta em lote com CSV de saída

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

Erros comuns e como resolver

  • Imagem CAPTCHA não carrega — cookie de sessão expirou → inicie sessão nova
  • "Sessão expirada" no formulário — resolução demorou demais → resolva perto do envio
  • Resposta CAPTCHA errada — imagem distorcida → denuncie via API
  • Automação bloqueada — detecção de IP/user-agent → use egress autorizado e UA real
  • Erro após o CAPTCHA — token expirou no servidor → resolva imediatamente antes de enviar

Perguntas frequentes

A CaptchaAI resolve o CAPTCHA do BLS?

Sim, com alta taxa de sucesso, usando method=bls para resolução direta ou method=base64 quando você só tem a imagem do desafio.

Automatizar o preenchimento de formulários em portais públicos é permitido?

Na maioria dos casos, sim — testar e operar os próprios formulários é um uso legítimo, comum em QA de tecnologia cívica. Confira os termos do portal específico antes de rodar em produção.

Quantas threads da CaptchaAI eu preciso para automatizar um portal público?

Depende do volume. O plano BASIC (US$ 15/mês, 5 threads) cobre agendamentos e consultas pontuais; para lotes maiores, o ADVANCE (US$ 90/mês, 50 threads) dá mais folga.

O que fazer quando a sessão expira antes de o CAPTCHA ser resolvido?

Resolva o CAPTCHA perto do envio do formulário, não no início do fluxo — o token do servidor tem vida curta. Se a janela de sessão for curta, abra uma sessão nova em vez de recuperar a antiga.


Guias Relacionados



Próximos passos

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