Casos de Uso

Manejo de CAPTCHA para la automatización de búsqueda de registros públicos

Los portales de registros públicos (sistemas judiciales, asesores de condados, presentaciones de la Secretaría de Estado, bases de datos de registros vitales) dependen en gran medida de CAPTCHA de imagen y OCR. Estos portales suelen utilizar implementaciones CAPTCHA más antiguas con texto distorsionado, problemas matemáticos o desafíos de imágenes personalizadas. A continuación se explica cómo manejarlos en diferentes tipos de registros.

Tipos comunes de CAPTCHA por portal

Categoría del portal CAPTCHA típico Ejemplos de desafíos
Búsqueda de casos judiciales CAPTCHA de texto personalizado Distorsión alfanumérica de 5 a 6 caracteres
Registros de propiedad del condado CAPTCHA de Matemáticas "¿Cuánto es 4 + 7?"
Búsqueda de entidades comerciales CAPTCHA del texto de la imagen Letras deformadas con ruido de línea
Registros vitales reCAPTCHA v2 Selección de cuadrícula de imágenes
Permisos de construcción CAPTCHA de texto simple código numérico de 4 dígitos
Presentaciones UCC CAPTCHA de OCR personalizado Letras mayúsculas y minúsculas mixtas con ruido de fondo

Búsqueda de registros públicos con resolución CAPTCHA

import requests
import base64
import time
from urllib.parse import urljoin

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

    def search_court_records(self, portal_url, case_number):
        """Search court records, solving image CAPTCHAs as needed."""
        # Load the search page
        page = self.session.get(f"{portal_url}/search")

        # Extract CAPTCHA image
        captcha_img_url = self._extract_captcha_url(page.text, portal_url)
        if not captcha_img_url:
            # No CAPTCHA on this page
            return self._submit_search(portal_url, case_number)

        # Download and solve CAPTCHA
        img_response = self.session.get(captcha_img_url)
        captcha_text = self._solve_image_captcha(img_response.content)

        # Submit search with solved CAPTCHA
        return self._submit_search(portal_url, case_number, captcha_text)

    def _extract_captcha_url(self, html, base_url):
        from bs4 import BeautifulSoup
        soup = BeautifulSoup(html, "html.parser")

        # Look for common CAPTCHA image patterns
        captcha_img = (
            soup.find("img", {"id": "captchaImage"}) or
            soup.find("img", {"class": "captcha"}) or
            soup.find("img", attrs={"src": lambda s: s and "captcha" in s.lower()})
        )

        if captcha_img and captcha_img.get("src"):
            return urljoin(base_url, captcha_img["src"])
        return None

    def _solve_image_captcha(self, image_bytes):
        img_base64 = base64.b64encode(image_bytes).decode("utf-8")

        resp = requests.post("https://ocr.captchaai.com/in.php", data={
            "key": self.api_key,
            "method": "base64",
            "body": img_base64,
            "json": 1
        })
        task_id = resp.json()["request"]

        for _ in range(30):
            time.sleep(3)
            result = requests.get("https://ocr.captchaai.com/res.php", params={
                "key": self.api_key,
                "action": "get",
                "id": task_id,
                "json": 1
            })
            data = result.json()
            if data["status"] == 1:
                return data["request"]

        raise TimeoutError("CAPTCHA solve timed out")

    def _submit_search(self, portal_url, case_number, captcha_text=None):
        form_data = {"caseNumber": case_number}
        if captcha_text:
            form_data["captcha"] = captcha_text

        response = self.session.post(
            f"{portal_url}/search/results",
            data=form_data
        )
        return response.text

# Usage
searcher = PublicRecordsSearcher("YOUR_API_KEY")
results = searcher.search_court_records(
    "https://courts.example.gov",
    "2024-CV-12345"
)

Manejo de CAPTCHA matemático

Algunos portales gubernamentales utilizan CAPTCHA matemáticos simples. CaptchaAI los maneja como reconocimiento de texto:

def solve_math_captcha(self, image_bytes):
    """Solve math CAPTCHAs like '4 + 7 = ?'"""
    img_base64 = base64.b64encode(image_bytes).decode("utf-8")

    resp = requests.post("https://ocr.captchaai.com/in.php", data={
        "key": self.api_key,
        "method": "base64",
        "body": img_base64,
        "textinstructions": "solve the math equation and return only the number",
        "json": 1
    })
    task_id = resp.json()["request"]

    # Poll for result
    for _ in range(30):
        time.sleep(3)
        result = requests.get("https://ocr.captchaai.com/res.php", params={
            "key": self.api_key,
            "action": "get",
            "id": task_id,
            "json": 1
        })
        data = result.json()
        if data["status"] == 1:
            return data["request"]

    raise TimeoutError("Math CAPTCHA solve timed out")

Búsqueda multiportal (JavaScript)

class RecordsAggregator {
  constructor(apiKey) {
    this.apiKey = apiKey;
  }

  async searchAcrossPortals(query, portals) {
    const results = [];

    for (const portal of portals) {
      try {
        const data = await this.searchPortal(portal, query);
        results.push({ portal: portal.name, records: data });
      } catch (error) {
        results.push({ portal: portal.name, error: error.message });
      }
    }

    return results;
  }

  async searchPortal(portal, query) {
    const pageResponse = await fetch(portal.searchUrl);
    const html = await pageResponse.text();

    // Check for image CAPTCHA
    const captchaMatch = html.match(/captcha[^"]*\.(?:png|jpg|gif)/i);
    let captchaAnswer = null;

    if (captchaMatch) {
      const imgUrl = new URL(captchaMatch[0], portal.searchUrl).href;
      const imgData = await fetch(imgUrl);
      const buffer = await imgData.arrayBuffer();
      const base64 = Buffer.from(buffer).toString('base64');

      captchaAnswer = await this.solveImageCaptcha(base64);
    }

    // Submit search
    const formData = new URLSearchParams({ q: query });
    if (captchaAnswer) formData.append('captcha', captchaAnswer);

    const response = await fetch(portal.searchUrl, {
      method: 'POST',
      body: formData
    });

    return response.text();
  }

  async solveImageCaptcha(base64Image) {
    const submitResp = await fetch('https://ocr.captchaai.com/in.php', {
      method: 'POST',
      body: new URLSearchParams({
        key: this.apiKey,
        method: 'base64',
        body: base64Image,
        json: '1'
      })
    });

    const { request: taskId } = await submitResp.json();

    for (let i = 0; i < 30; i++) {
      await new Promise(r => setTimeout(r, 3000));
      const result = await fetch(
        `https://ocr.captchaai.com/res.php?key=${this.apiKey}&action=get&id=${taskId}&json=1`
      );
      const data = await result.json();
      if (data.status === 1) return data.request;
    }

    throw new Error('CAPTCHA solve timed out');
  }
}

// Usage
const aggregator = new RecordsAggregator('YOUR_API_KEY');
const results = await aggregator.searchAcrossPortals('Smith LLC', [
  { name: 'State Business Registry', searchUrl: 'https://sos.example.gov/search' },
  { name: 'County Court Records', searchUrl: 'https://courts.example.gov/search' }
]);

Parámetros CAPTCHA para portales gubernamentales

Parámetro Valor cuando usar
method base64 Imagen descargada como bytes
method post Enviar archivo de imagen directamente
language 0 CAPTCHA de texto /Latin
numeric 1 CAPTCHA de solo dígitos
min_len / max_len Varía Cuando el número de caracteres es predecible
textinstructions Mensaje personalizado CAPTCHA de matemáticas o formatos específicos

Solución de problemas

Problema causa Solución
La imagen CAPTCHA devuelve 403 Falta la cookie de sesión Cargue la página de búsqueda primero, luego busque la imagen
Respuesta CAPTCHA incorrecta Baja calidad de imagen Imagen de preprocesamiento (aumentar el contraste, eliminar el ruido)
CAPTCHA se actualiza al enviar El token del formulario expiró Extraiga campos de formulario ocultos con CAPTCHA
La búsqueda vuelve vacía después de CAPTCHA POST redireccionamiento de cookies perdidas Utilice allow_redirects=True y persista la sesión

Preguntas frecuentes

¿Por qué los portales gubernamentales todavía utilizan CAPTCHA de imágenes?

Muchos sistemas gubernamentales ejecutan software heredado anterior a reCAPTCHA y Cloudflare Turnstile. Los CAPTCHA de imágenes personalizadas eran el estándar cuando se crearon estos sistemas y las actualizaciones son lentas en la TI gubernamental.

¿Qué tan preciso es CaptchaAI para CAPTCHA de texto distorsionado?

CaptchaAI admite más de 27.500 tipos de imágenes CAPTCHA con alta precisión. Para texto muy distorsionado, utilice el parámetro textinstructions para guiar el reconocimiento; por ejemplo, "letras y números, sin espacios".

¿Debo preprocesar las imágenes CAPTCHA antes de enviarlas?

El preprocesamiento (escala de grises, aumento de contraste, eliminación de ruido) puede mejorar la precisión de imágenes de muy baja calidad. Ver elguía de preprocesamiento de imágenespara técnicas.

Próximos pasos

Automatizar las búsquedas de registros públicos:obtenga su clave API CaptchaAIy manejar CAPTCHA de portales gubernamentales.


Siguientes pasos

  • Inicio rápido de CaptchaAI: tu primera resolución de CAPTCHA en 5 minutos
  • Cómo resolver reCAPTCHA v2 con la API: guía paso a paso
  • Cómo resolver Cloudflare Turnstile con la API
  • Cómo resolver GeeTest v3 usando API
Los comentarios están deshabilitados para este artículo.