Kullanım Senaryoları

Uçuş Durumu İzleme için CAPTCHA Kullanımı

Uçuş durumunun izlenmesi, birden fazla havayolu ve havaalanı portalında sık sık kontrol yapılmasını gerektirir. Bu portallar, gerçek zamanlı verilerini Cloudflare Turnstile, reCAPTCHA ve özel CAPTCHA'larla (özellikle tekrarlanan otomatik sorguları tespit ettiklerinde) korur. Güvenilir uçuş takip araçları oluştururken CAPTCHA'ları nasıl yöneteceğiniz burada açıklanmıştır.

CAPTCHA'ların Göründüğü Yer

Portal türü CAPTCHA Tetikleyici
Havayolu uçuş durumu sayfası Cloudflare Turnstile Aynı IP'den sık istekler
Havaalanına varış/departure panoları Cloudflare doğrulama akışı Bot tespiti
Uçuş arama motorları reCAPTCHA v2/v3 Arama formu gönderimi
Rezervasyon durumu kontrolü reCAPTCHA v2 Seyahat planını göstermeden önce
API hız sınırı sayfaları Özel CAPTCHA İstek sınırlarını aştıktan sonra

Uçuş İzleme Mimarisi

import requests
import time
from datetime import datetime

class FlightMonitor:
    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 check_flight(self, airline_url, flight_number):
        """Check flight status, handling CAPTCHAs if encountered."""
        response = self.session.get(
            f"{airline_url}/flight-status/{flight_number}"
        )

        if self._is_captcha_page(response):
            response = self._solve_and_retry(response, airline_url)

        return self._parse_flight_data(response.text)

    def _is_captcha_page(self, response):
        return (
            response.status_code == 403 or
            "cf-turnstile" in response.text or
            "g-recaptcha" in response.text
        )

    def _solve_and_retry(self, response, url):
        import re

        # Detect CAPTCHA type
        if "cf-turnstile" in response.text:
            match = re.search(r'data-sitekey="(0x[^"]+)"', response.text)
            token = self._solve_turnstile(match.group(1), url)
            field = "cf-turnstile-response"
        else:
            match = re.search(r'data-sitekey="([^"]+)"', response.text)
            token = self._solve_recaptcha(match.group(1), url)
            field = "g-recaptcha-response"

        return self.session.post(url, data={field: token})

    def _solve_turnstile(self, site_key, page_url):
        resp = requests.post("https://ocr.captchaai.com/in.php", data={
            "key": self.api_key,
            "method": "turnstile",
            "sitekey": site_key,
            "pageurl": page_url,
            "json": 1
        })
        task_id = resp.json()["request"]
        return self._poll_result(task_id)

    def _solve_recaptcha(self, site_key, page_url):
        resp = requests.post("https://ocr.captchaai.com/in.php", data={
            "key": self.api_key,
            "method": "userrecaptcha",
            "googlekey": site_key,
            "pageurl": page_url,
            "json": 1
        })
        task_id = resp.json()["request"]
        return self._poll_result(task_id)

    def _poll_result(self, task_id):
        for _ in range(60):
            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 _parse_flight_data(self, html):
        # Parse flight status from HTML
        from bs4 import BeautifulSoup
        soup = BeautifulSoup(html, "html.parser")

        def text_or_none(node):
            return node.text.strip() if node and node.text else None

        return {
            "status": text_or_none(soup.select_one(".flight-status")),
            "departure": text_or_none(soup.select_one(".departure-time")),
            "arrival": text_or_none(soup.select_one(".arrival-time")),
            "gate": text_or_none(soup.select_one(".gate-info")),
            "checked_at": datetime.now().isoformat()
        }

CAPTCHA İşleme ile Periyodik İzleme

def monitor_flight(monitor, airline_url, flight_number, 
                   interval_seconds=300, max_checks=48):
    """Monitor a flight every N seconds, handling CAPTCHAs as needed."""
    history = []

    for check_num in range(max_checks):
        try:
            status = monitor.check_flight(airline_url, flight_number)
            history.append(status)

            # Alert on changes
            if len(history) > 1 and status["status"] != history[-2]["status"]:
                print(f"Status changed: {history[-2]['status']} → {status['status']}")

            print(f"Check {check_num + 1}: {status['status']} "
                  f"(Gate: {status.get('gate', 'Coming soon')})")

        except Exception as e:
            print(f"Check {check_num + 1} failed: {e}")

        time.sleep(interval_seconds)

    return history

# Usage
monitor = FlightMonitor("YOUR_API_KEY")
monitor_flight(monitor, "https://airline.example.com", "AA1234")

Çoklu Havayolu İzleme (JavaScript)

class FlightTracker {
  constructor(apiKey) {
    this.apiKey = apiKey;
    this.flights = new Map();
  }

  async addFlight(airline, flightNumber, checkUrl) {
    this.flights.set(flightNumber, {
      airline,
      url: checkUrl,
      history: [],
      lastCheck: null
    });
  }

  async checkAll() {
    const results = [];

    for (const [flightNum, flight] of this.flights) {
      try {
        const status = await this.checkFlight(flight.url, flightNum);
        flight.history.push(status);
        flight.lastCheck = new Date();
        results.push({ flight: flightNum, ...status });
      } catch (error) {
        results.push({ flight: flightNum, error: error.message });
      }
    }

    return results;
  }

  async checkFlight(url, flightNumber) {
    const response = await fetch(`${url}/status/${flightNumber}`);
    const html = await response.text();

    // Check for CAPTCHA
    if (html.includes('cf-turnstile') || response.status === 403) {
      return this.solveAndRetry(url, flightNumber, html);
    }

    return this.parseStatus(html);
  }

  async solveAndRetry(url, flightNumber, html) {
    const siteKeyMatch = html.match(/data-sitekey="(0x[^"]+)"/);
    if (!siteKeyMatch) throw new Error('No sitekey found');

    const token = await this.solveTurnstile(siteKeyMatch[1], url);

    const response = await fetch(`${url}/status/${flightNumber}`, {
      method: 'POST',
      body: new URLSearchParams({ 'cf-turnstile-response': token })
    });

    return this.parseStatus(await response.text());
  }
}

İzleme Sıklığı ve CAPTCHA Oranları

Frekansı kontrol edin Tipik CAPTCHA oranı Tavsiye
Her 1 dakikada bir Yüksek (%50-80) Çok agresif – aralığı artırın
Her 5 dakikada bir Orta (%10-30) Kritik uçuşlar için kabul edilebilir
Her 15 dakikada bir Düşük (%5-10) Rutin izleme için iyi denge
Her 30 dakikada bir Çok düşük (<%5) Uzun vadeli izleme için en iyisi
Her saat Minimal (<%1) CAPTCHA'lar nadiren tetiklenir

Oturum Optimizasyonu

Oturum durumunu koruyarak CAPTCHA karşılaşmalarını azaltın:

Teknik Etki
Kontroller arasında çerezlerin kalıcı olmasını sağlayın Cloudflare qa_session_cookie 15-30 dakika süreyle geçerlidir
Tutarlı Kullanıcı Aracısı kullanın UA'yı değiştirmek yeni zorlukları tetikliyor
Proxy tutarlılığını koruyun Aynı IP şüpheyi azaltır
Eşit alan istekleri Patlama modelleri hız sınırlarını tetikler

Sorun giderme

Sorun Sebep Düzeltme
CAPTCHA her kontrolde Oturum devam etmedi requests.Session()'yi kontrollerde yeniden kullanın
Cloudflare bloğu (Hata 1020) Çok fazla istek Kontrol aralığını artırın
CAPTCHA'dan sonra uçuş verileri güncelliğini yitirdi Çözüm sırasında belirtecin süresi doldu Tam zamanında çözmeyi kullanın
Tarayıcının gösterdiğinden farklı veriler Eksik JavaScript oluşturma JS ağırlıklı siteler için tarayıcı otomasyonunu kullanın

SSS

Uçuş durumunu ne sıklıkla kontrol etmeliyim?

Her 5-15 dakikada bir normaldir. Daha sık kontroller daha fazla CAPTCHA'yı tetikler ve IP engellemelerine neden olabilir. CaptchaAI Turnstileyi %100 başarı oranıyla yönetir, dolayısıyla sınırlayıcı faktör CAPTCHA çözümü değil, portalın hız sınırlarıdır.

Birden fazla havayolunun uçuşlarını aynı anda izleyebilir miyim?

Evet. Her havayolu için ayrı oturumlar kullanın ve her biri için CAPTCHA'ları bağımsız olarak çözün. CaptchaAI, farklı sitelerdeki eşzamanlı istekleri yönetir.

Havayolu mobil API'lerinin CAPTCHA'ları var mı?

Mobil API'ler genellikle CAPTCHA'lar yerine farklı kimlik doğrulama (API anahtarları, OAuth) kullanır. Ancak hizmet verdikleri web uç noktaları hâlâ Cloudflare korumasına sahip olabilir.

İlgili Makaleler

Sonraki Adımlar

Güvenilir uçuş izleme sistemi oluşturun —CaptchaAI API anahtarınızı alınve havayolu CAPTCHA'larını otomatik olarak yönetin.

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