Casos de Uso

Monitoramento de tarifas aéreas com tratamento CAPTCHA

Sites de viagens e companhias aéreas usam frequentemente CAPTCHAs para limitar a verificação automatizada de tarifas. Um sistema de monitoramento de preços que verifica tarifas em diversas rotas encontrará desafios de reCAPTCHA, intersticiais da Cloudflare e mecanismos de limitação de tarifas. CaptchaAI cuida da etapa de resolução de CAPTCHA para que seu pipeline de monitoramento possa continuar coletando dados de tarifas.

Este guia mostra como construir um fluxo de trabalho de monitoramento de tarifas que detecte e resolva CAPTCHAs durante verificações de preços.


O fluxo de trabalho de monitoramento

Schedule check → Request fare page → CAPTCHA detected?
                                         ↓ Yes
                                    Solve via CaptchaAI → Inject token → Retry request
                                         ↓ No
                                    Parse fare data → Store → Alert on price change

O que você precisa

Requisito Detalhes
Chave de API CaptchaAI captchaai.com
Python 3.8+ Com requests
Procurador egress de rede autorizado para sites de viagens
pip install requests

Ajudante de resolução CaptchaAI

import requests
import time

API_KEY = "YOUR_API_KEY"


def solve_recaptcha_v2(sitekey, pageurl):
    """Solve reCAPTCHA v2 and return the token."""
    submit = requests.post("https://ocr.captchaai.com/in.php", data={
        "key": API_KEY, "method": "userrecaptcha",
        "googlekey": sitekey, "pageurl": pageurl, "json": 1
    }).json()

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

    task_id = submit["request"]
    time.sleep(20)

    for _ in range(30):
        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"]
        if result.get("request") != "CAPCHA_NOT_READY":
            raise RuntimeError(f"Solve error: {result['request']}")
        time.sleep(5)
    raise TimeoutError("Solve timed out")


def solve_turnstile(sitekey, pageurl):
    """Solve Cloudflare Turnstile and return the token."""
    submit = requests.post("https://ocr.captchaai.com/in.php", data={
        "key": API_KEY, "method": "turnstile",
        "sitekey": sitekey, "pageurl": pageurl, "json": 1
    }).json()

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

    task_id = submit["request"]
    time.sleep(10)

    for _ in range(30):
        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"]
        if result.get("request") != "CAPCHA_NOT_READY":
            raise RuntimeError(f"Solve error: {result['request']}")
        time.sleep(5)
    raise TimeoutError("Solve timed out")

Monitoramento de tarifas com manipulação de CAPTCHA

import json
from datetime import datetime


class FareMonitor:
    def __init__(self, proxy=None):
        self.session = requests.Session()
        if proxy:
            self.session.proxies = {
                "http": f"http://{proxy}",
                "https": f"http://{proxy}"
            }
        self.fare_history = {}

    def check_fare(self, route):
        """Check fare for a route, solving CAPTCHAs if needed."""
        url = route["url"]

        response = self.session.get(url)

        # Detect CAPTCHA in response
        if self._has_recaptcha(response.text):
            sitekey = self._extract_sitekey(response.text)
            token = solve_recaptcha_v2(sitekey, url)
            response = self.session.post(url, data={
                "g-recaptcha-response": token,
                **route.get("params", {})
            })

        elif self._has_turnstile(response.text):
            sitekey = self._extract_turnstile_key(response.text)
            token = solve_turnstile(sitekey, url)
            response = self.session.post(url, data={
                "cf-turnstile-response": token,
                **route.get("params", {})
            })

        return self._parse_fare(response.text, route)

    def _has_recaptcha(self, html):
        return "g-recaptcha" in html or "recaptcha/api" in html

    def _has_turnstile(self, html):
        return "cf-turnstile" in html or "turnstile" in html

    def _extract_sitekey(self, html):
        # Extract data-sitekey from reCAPTCHA div
        if 'data-sitekey="' in html:
            start = html.index('data-sitekey="') + 14
            end = html.index('"', start)
            return html[start:end]
        return None

    def _extract_turnstile_key(self, html):
        if 'data-sitekey="' in html:
            idx = html.index("cf-turnstile")
            start = html.index('data-sitekey="', idx) + 14
            end = html.index('"', start)
            return html[start:end]
        return None

    def _parse_fare(self, html, route):
        """Parse fare data from the response. Customize per target site."""
        # Placeholder — implement per site
        return {
            "route": route["name"],
            "timestamp": datetime.now().isoformat(),
            "raw_length": len(html)
        }

    def monitor_routes(self, routes):
        """Check all routes and report price changes."""
        results = []
        for route in routes:
            try:
                fare = self.check_fare(route)
                results.append(fare)
                print(f"[OK] {route['name']}: checked")
            except Exception as e:
                print(f"[ERROR] {route['name']}: {e}")
        return results


# Usage
routes = [
    {
        "name": "NYC-LAX",
        "url": "https://example-airline.com/search?from=JFK&to=LAX&date=2025-08-15",
        "params": {"adults": 1}
    },
    {
        "name": "SFO-ORD",
        "url": "https://example-airline.com/search?from=SFO&to=ORD&date=2025-08-20",
        "params": {"adults": 1}
    }
]

monitor = FareMonitor(proxy="user:pass@proxy.example.com:8080")
results = monitor.monitor_routes(routes)

for r in results:
    print(json.dumps(r, indent=2))

Agendamento de verificações

Execute o monitor de acordo com uma programação usando cron ou um agendador de tarefas:

# Check fares every 6 hours
0 */6 * * * cd /path/to/project && python fare_monitor.py >> /var/log/fares.log 2>&1

Lista de verificação de captura de tarifas

  • Capture tarifas básicas, impostos, moeda e família de tarifas em uma carga útil para que comparações posteriores permaneçam utilizáveis.
  • Mantenha pelo menos dois substitutos do seletor e armazene um instantâneo HTML bruto sempre que a análise falhar.
  • Registre a rota, a data de partida, o horário de coleta e a latência do CAPTCHA com cada evento resolvido.

Solução de problemas

Problema Causa Correção
CAPTCHAs frequentes Muitas solicitações do mesmo IP Use proxies residenciais rotativos
Preços obsoletos Páginas em cache Adicione cabeçalhos que impeçam o cache ou torne os parâmetros de solicitação aleatórios
IP bloqueado Limitação de taxa Aumente os atrasos entre as verificações, alterne os proxies
A resolução do CAPTCHA falha Extração de chave de site errada Verifique se a chave do site corresponde ao CAPTCHA na página

Perguntas frequentes

Com que frequência devo verificar as tarifas?

A cada 4-8 horas é normal. Verificações mais frequentes aumentam os encontros CAPTCHA e os custos de proxy.

Quais tipos de CAPTCHA os sites de companhias aéreas usam?

Mais comumente páginas reCAPTCHA v2, Cloudflare Turnstile ou Challenge e, ocasionalmente, CAPTCHAs de imagem.

Eu preciso de proxies residenciais?

Sim. Sites de viagens bloqueiam ativamente IPs de datacenters. Os proxies residenciais ou móveis têm taxas de sucesso significativamente mais altas.

Posso monitorar várias companhias aéreas?

Sim. Personalize o método _parse_fare para o formato de resposta de cada companhia aérea e adicione rotas para cada site.

Como lidar com as páginas Cloudflare Turnstile em staging?

Use method=turnstile_staging com um proxy. O cookie cookie_qa_validacao retornado concede acesso ao site. Veja oGuia Cloudflare Turnstile em staging.


Obtenha sua chave API CaptchaAI

Comece a monitorar as tarifas aéreas emcaptchaai.com. Lide com CAPTCHAs automaticamente em seu fluxo de trabalho de rastreamento de preços.


Guias relacionados

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