Seyahat ve havayolu siteleri, otomatik ücret kontrolünü sınırlamak için sıklıkla CAPTCHA'ları kullanır. Birden fazla rotadaki ücretleri kontrol eden bir fiyat izleme sistemi, reCAPTCHA zorluklarıyla, Cloudflare geçiş reklamlarıyla ve hız sınırlayıcı mekanizmalarla karşılaşacaktır. CaptchaAI, CAPTCHA çözme adımını gerçekleştirerek izleme işlem hattınızın ücret verilerini toplamaya devam edebilmesini sağlar.
Bu kılavuz, fiyat kontrolleri sırasında CAPTCHA'ları algılayan ve çözen bir ücret izleme iş akışının nasıl oluşturulacağını gösterir.
İzleme iş akışı
Schedule check → Request fare page → CAPTCHA detected?
↓ Yes
Solve via CaptchaAI → Inject token → Retry request
↓ No
Parse fare data → Store → Alert on price change
İhtiyacınız olan şey
| Gereksinim | Ayrıntılar |
|---|---|
| CaptchaAI API anahtarı | captchaai.com |
| Python 3.8+ | requests ile |
| Vekil | Seyahat siteleri için konut vekili |
pip install requests
CaptchaAI çözücü yardımcısı
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")
CAPTCHA kullanımıyla ücret izleme
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))
Kontrollerin planlanması
Monitörü cron veya görev zamanlayıcı kullanarak bir zamanlamaya göre çalıştırın:
# Check fares every 6 hours
0 */6 * * * cd /path/to/project && python fare_monitor.py >> /var/log/fares.log 2>&1
Ücret yakalama kontrol listesi
- Temel ücreti, vergileri, para birimini ve ücret ailesini tek bir veri yükünde yakalayın, böylece daha sonraki karşılaştırmalar kullanılabilir kalır.
- En az iki seçici yedeği bulundurun ve ayrıştırma başarısız olduğunda ham HTML anlık görüntüsünü saklayın.
- Her çözüm olayında rotayı, kalkış tarihini, toplama süresini ve CAPTCHA gecikmesini kaydedin.
Sorun giderme
| Sorun | Sebep | Düzeltme |
|---|---|---|
| Sık CAPTCHA'lar | Aynı IP'den çok fazla istek var | Dönüşümlü kendi sunucu altyapınız'leri kullanın |
| Eski fiyatlar | Önbelleğe alınmış sayfalar | Önbellek bozan başlıklar ekleyin veya istek parametrelerini rastgele hale getirin |
| IP engellendi | Hız sınırlaması | Kontroller arasındaki gecikmeleri artırın, proxy'leri döndürün |
| CAPTCHA çözümü başarısız oluyor | Yanlış site anahtarı çıkarma | Site anahtarının sayfadaki CAPTCHA ile eşleştiğini doğrulayın |
SSS
Ücretleri ne sıklıkla kontrol etmeliyim?
Her 4-8 saatte bir normaldir. Daha sık yapılan kontroller CAPTCHA karşılaşmalarını ve proxy maliyetlerini artırır.
Havayolu siteleri hangi CAPTCHA türlerini kullanıyor?
En yaygın olarak reCAPTCHA v2, Cloudflare Turnstile veya Challenge sayfaları ve bazen de resim CAPTCHA'ları.
Konut vekillerine ihtiyacım var mı?
Evet. Seyahat siteleri veri merkezi IP'lerini aktif olarak engelliyor. Yerleşik veya kendi sunucu altyapınız'lerin başarı oranları önemli ölçüde daha yüksektir.
Birden fazla havayolunu izleyebilir miyim?
Evet. Her havayolunun yanıt formatı için _parse_fare yöntemini özelleştirin ve her site için rota ekleyin.
Cloudflare doğrulama akışı sayfalarını nasıl yönetirim?
method=cloudflare_challenge'yi bir proxy ile kullanın. Döndürülen qa_session_cookie çerezi siteye erişim sağlar. Bkz.Cloudflare doğrulama akışı kılavuzu.
CaptchaAI API anahtarınızı alın
Havayolu ücretlerini şu adresten izlemeye başlayın:captchaai.com. Fiyat izleme iş akışınızda CAPTCHA'ları otomatik olarak işleyin.