import asyncio
import time
import json
import certifi
import cloudscraper
import random
from fake_useragent import UserAgent
import os
from datetime import datetime
NUM_POLLING_WORKERS = 7
STATUS_UPDATE_INTERVAL = 0.5
ACCEPT_RETRY_DELAY = 1.5
MAX_ACCEPT_RETRIES = 2
ACCEPT_TIMEOUT = 20
BOOKING_URL = "api1"
ACCEPT_URL = "api2"
LOGIN_HASH = "hash1"
ACCEPT_LOGIN_HASH = "hash2"
VEHICLE_ID = "36979"
TELEGRAM_BOT_TOKEN = "token"
TELEGRAM_CHAT_ID = "id"
PROXY_FILE = "proxy.txt"
previous_hashes = set()
lock = asyncio.Lock()
success_count = 0
ua = UserAgent()
loaded_proxies = []
try:
accept_scraper = cloudscraper.create_scraper(
browser={"browser": "chrome", "platform": "windows", "mobile": False}
)
print("\n✅ Kabul istekleri için Cloudscraper başarıyla başlatıldı.")
except Exception as e:
print(f"\n❌ Kabul istekleri için Cloudscraper başlatılamadı: {e}")
accept_scraper = None # Hata durumunda None olarak ayarla
# ---------------------------------------------
# ===================================
# FONKSİYONLAR
# ===================================
def get_current_time_ms():
return datetime.now().strftime('%H:%M:%S.%f')[:-3]
def load_proxies_from_file(filename=PROXY_FILE):
"""proxy.txt dosyasından ip:port:user:pass formatındaki proxy'leri okur."""
proxies = []
if not os.path.exists(filename):
print(f"\n❌ HATA: Proxy dosyası bulunamadı: {filename}")
return []
try:
with open(filename, 'r') as f:
for line_num, line in enumerate(f):
line = line.strip()
if not line or line.startswith('#'):
continue
parts = line.split(':')
if len(parts) == 4:
ip, port, username, password = parts
# IPv6 adresleri için köşeli parantez kontrolü
if ':' in ip and not (ip.startswith('[') and ip.endswith(']')):
ip = f"[{ip}]" # Köşeli parantez ekle
proxy_url = f"http://{username}:{password}@{ip}:{port}"
proxy_dict = {"http": proxy_url, "https": proxy_url}
proxies.append(proxy_dict)
else:
print(f"\n⚠️ Uyarı: {filename} dosyasındaki {line_num+1}. satır geçersiz formatta: '{line}'. Format ip:port:user:pass olmalı.")
except Exception as e:
print(f"\n❌ HATA: Proxy dosyası okunurken hata oluştu ({filename}): {e}")
return []
if not proxies:
print(f"\n❌ HATA: {filename} dosyasından geçerli proxy yüklenemedi.")
else:
print(f"\n✅ {len(proxies)} adet proxy başarıyla yüklendi: {filename}")
return proxies
def get_random_headers():
"""Rastgele User-Agent ile HTTP başlıkları oluşturur."""
return {
"Content-Type": "application/json",
"User-Agent": ua.random
}
# ==========================================================
# === send_telegram_message (SSL Hatası için Düzeltildi) ===
# ==========================================================
async def send_telegram_message(message):
"""Telegram'a asenkron olarak bildirim gönderir (SSL doğrulaması ile)."""
if not TELEGRAM_BOT_TOKEN or not TELEGRAM_CHAT_ID:
# print("\nℹ️ Telegram token veya chat ID ayarlanmadığı için bildirim gönderilmedi.")
return
url = f"https://api.telegram.org/bot{TELEGRAM_BOT_TOKEN}/sendMessage"
payload = {"chat_id": TELEGRAM_CHAT_ID, "text": message, "parse_mode": "Markdown"}
sender_scraper = None
try:
# Telegram için ayrı, basit bir scraper kullan
sender_scraper = cloudscraper.create_scraper()
# Cloudscraper doğrudan async context manager desteklemez, to_thread kullanmak daha güvenli
response = await asyncio.to_thread(
sender_scraper.post,
url,
json=payload,
timeout=15,
verify=certifi.where()
)
if response.status_code != 200:
response_text = response.text
print(f"\n[{get_current_time_ms()}] ❌ Telegram Hatası: {response.status_code} - {response_text[:200]}")
except asyncio.TimeoutError:
print(f"\n[{get_current_time_ms()}] ⚠️ Telegram Bağlantı Hatası: Zaman aşımı (Timeout)")
except Exception as e:
print(f"\n[{get_current_time_ms()}] ⚠️ Telegram Bağlantı Hatası: {type(e).__name__} - {e}")
finally:
if sender_scraper:
pass
# ==========================================================
# === /send_telegram_message ===
# ==========================================================
async def accept_booking(booking_hash):
"""Bir rezervasyonu PROXYSİZ olarak kabul etmeye çalışır (Geliştirilmiş Loglama ile)."""
global previous_hashes
global lock
global accept_scraper # Global scraper'ı kullan
start_time_accept = get_current_time_ms()
if accept_scraper is None:
print(f"\n[{start_time_accept}] 🚫 Kabul Scraper başlatılamadığı için kabul işlemi yapılamıyor: {booking_hash}")
return False
# --- Hash Kontrolü (Kilitle) ---
async with lock:
if booking_hash in previous_hashes:
# print(f"\n[{start_time_accept}] ℹ️ Zaten işleniyor/işlendi: {booking_hash}") # Çok sık log olmaması için yorumda
return False # Zaten işleniyorsa veya işlendiyse çık
previous_hashes.add(booking_hash)
# -----------------------------
print(f"\n[{start_time_accept}] 🚀 Kabul işlemi başlatıldı (PROXYSİZ): {booking_hash}")
accept_payload = {
"login_hash": ACCEPT_LOGIN_HASH,
"booking_hash": booking_hash,
"vehicle_id": VEHICLE_ID,
"refuse": "accept"
}
headers = get_random_headers()
for attempt in range(MAX_ACCEPT_RETRIES):
current_time_attempt = get_current_time_ms()
print(f" [{current_time_attempt}] ➡️ Kabul Denemesi {attempt + 1}/{MAX_ACCEPT_RETRIES} gönderiliyor: {booking_hash}")
try:
accept_response = await asyncio.to_thread(
accept_scraper.post, # Global scraper'ı kullan
ACCEPT_URL,
headers=headers,
json=accept_payload,
verify=certifi.where(), # Burada zaten vardı
timeout=ACCEPT_TIMEOUT # Ayarlanan timeout
)
current_time_response = get_current_time_ms()
response_text_snippet = accept_response.text[:200] if accept_response.text else "Yanıt yok" # Hata mesajını kısalt
if accept_response.status_code == 200:
print(f" [{current_time_response}] ✅ BAŞARILI KABUL! (PROXYSİZ) - Deneme {attempt + 1}: {booking_hash}")
message = f"✅ Rezervasyon Kabul Edildi!\n\nHash: `{booking_hash}`\nZaman: {current_time_response}\n\n🔗 [Detay](https://site.com/{booking_hash})"
asyncio.create_task(send_telegram_message(message)) # Telegram'a gönder
return True # Başarılı, fonksiyondan çık
else:
# --- Detaylı Hata Loglaması ---
print(f" [{current_time_response}] ❌ KABUL HATASI (PROXYSİZ) - Durum Kodu: {accept_response.status_code} - Deneme {attempt + 1}/{MAX_ACCEPT_RETRIES}")
print(f" Yanıt Başlangıcı: {response_text_snippet}...")
print(f" Hash: {booking_hash}")
# ------------------------------
if 400 <= accept_response.status_code < 500:
print(f" [{current_time_response}] 🛑 4xx hatası alındı, tekrar denenmeyecek: {booking_hash}")
return False # Tekrar deneme
if attempt + 1 < MAX_ACCEPT_RETRIES:
wait_time = ACCEPT_RETRY_DELAY * (2 ** attempt) # Exponential backoff
print(f" [{current_time_response}] ⏳ {wait_time:.1f} sn bekleniyor...")
await asyncio.sleep(wait_time)
except Exception as e:
current_time_exception = get_current_time_ms()
# --- Detaylı İstisna Loglaması ---
print(f" [{current_time_exception}] ⚠️ KABUL BAĞLANTI/İSTİSNA HATASI (PROXYSİZ) - Deneme {attempt + 1}/{MAX_ACCEPT_RETRIES}")
print(f" Hata: {type(e).__name__} - {e}")
print(f" Hash: {booking_hash}")
# ------------------------------
if attempt + 1 < MAX_ACCEPT_RETRIES:
wait_time = ACCEPT_RETRY_DELAY * (2 ** attempt) # Exponential backoff
print(f" [{current_time_exception}] ⏳ {wait_time:.1f} sn bekleniyor...")
await asyncio.sleep(wait_time)
final_fail_time = get_current_time_ms()
print(f"\n[{final_fail_time}] 🚫 KABUL BAŞARISIZ (PROXYSİZ) (Tüm denemeler bitti): {booking_hash}")
return False
# =============================================
# === check_new_bookings FONKSİYONU (await ile güncellendi) ===
# =============================================
async def check_new_bookings(response_text):
"""
API yanıtını kontrol eder ve yeni rezervasyonları kabul için İŞLEME ALIR.
(await kullanıldığı için, bu fonksiyon içinde rezervasyonlar sırayla işlenir)
"""
try:
data = json.loads(response_text)
# Anahtar varlık kontrollerini artır
if not isinstance(data, dict): return
api_data = data.get("data")
if not isinstance(api_data, dict): return
current_bookings = api_data.get("bookings")
if not isinstance(current_bookings, list): return
except json.JSONDecodeError as e:
# print(f"\n[{get_current_time_ms()}] ⚠️ JSON Decode Hatası: {e} - Yanıt: {response_text[:100]}...") # Gürültülü olabilir
return
except Exception as e:
print(f"\n[{get_current_time_ms()}] ❌ Beklenmedik Hata (check_new_bookings): {type(e).__name__} - {e}")
return
if current_bookings:
current_time_check = get_current_time_ms()
print(f"\n[{current_time_check}] Yeni rezervasyon(lar) bulundu ({len(current_bookings)} adet). Sırayla işleniyor...")
for booking in current_bookings:
if isinstance(booking, dict) and "booking_hash_link" in booking:
booking_hash = booking["booking_hash_link"]
# Log mesajını güncelle (bekleme olduğunu belirtmek için)
print(f" -> [{get_current_time_ms()}] ✨ REZERVASYON: {booking_hash} -> Kabul işlemi başlatılıyor ve bekleniyor (await)...")
try:
# === DEĞİŞİKLİK BURADA (Önceki adımda yapıldı) ===
# accept_booking fonksiyonunu çağır ve tamamlanmasını bekle.
success = await accept_booking(booking_hash)
# ============================================
if success:
pass
else:
pass
except Exception as e:
print(f" -> [{get_current_time_ms()}] ❌ KRİTİK HATA (check_new_bookings içinde await sırasında): {booking_hash} - {e}")
else:
print(f" -> [{get_current_time_ms()}] ⚠️ Geçersiz rezervasyon verisi formatı atlandı: {booking}")
print(f"--- [{get_current_time_ms()}] Bulunan rezervasyonların işlenmesi tamamlandı (check_new_bookings). ---")
# =============================================
# === /check_new_bookings FONKSİYONU ===
# =============================================
async def poll_worker(worker_id):
global success_count
global lock
global loaded_proxies
# Her worker için ayrı scraper instance
worker_scraper = None # Başlangıçta None
try:
worker_scraper = cloudscraper.create_scraper(
browser={"browser": "chrome", "platform": "windows", "mobile": False}
)
except Exception as e:
print(f"[{get_current_time_ms()}] [Worker {worker_id}] ❌ Başlatılamadı: Scraper oluşturma hatası: {e}")
return # Scraper oluşturulamazsa worker çalışamaz
polling_interval = 0 # Başlangıçta bekleme yok
MAX_POLL_RETRIES = 1 # Sorgu için tekrar deneme sayısı
POLL_RETRY_DELAY = 1 # Sorgu tekrar deneme gecikmesi
while True:
await asyncio.sleep(polling_interval) # Döngüler arası (varsa) bekleme
if not loaded_proxies:
await asyncio.sleep(10)
continue
# --- Proxy Seçimi ve İstek Hazırlığı ---
try:
proxies = random.choice(loaded_proxies)
except IndexError:
await asyncio.sleep(5)
continue
headers = get_random_headers()
response = None
# ------------------------------------
for attempt in range(MAX_POLL_RETRIES):
try:
payload = {"login_hash": LOGIN_HASH}
response = await asyncio.to_thread(
worker_scraper.post,
BOOKING_URL,
headers=headers,
json=payload,
verify=certifi.where(), # Sorgulama için de SSL doğrulama ekleyelim
proxies=proxies,
timeout=15 # Sorgu timeout'u
)
if response.status_code == 200:
async with lock:
success_count += 1
response_text = response.text
asyncio.create_task(check_new_bookings(response_text))
polling_interval = 0 # Başarılı ise hemen tekrar dene
break # Başarılı, deneme döngüsünden çık
else:
if 400 <= response.status_code < 500:
polling_interval = 0.5
break #
if attempt + 1 < MAX_POLL_RETRIES:
await asyncio.sleep(POLL_RETRY_DELAY * (2 ** attempt))
else:
polling_interval = 0.5 #
except Exception as e:
polling_interval = 0.5
if attempt + 1 < MAX_POLL_RETRIES:
await asyncio.sleep(POLL_RETRY_DELAY * (2 ** attempt))
async def status_updater():
global success_count
global lock
last_print_time = time.monotonic()
while True:
await asyncio.sleep(max(0, STATUS_UPDATE_INTERVAL - (time.monotonic() - last_print_time)))
last_print_time = time.monotonic()
async with lock:
current_count = success_count
current_time_str = get_current_time_ms()
print(f"\r🔄 Toplam Başarılı Sorgu: {current_count} | Zaman: {current_time_str} ", end="")
# ===================================
# ANA PROGRAM YÖNETİMİ
# ===================================
async def main():
"""Worker ve status task'larını başlatır ve çalışmasını bekler."""
global loaded_proxies
global accept_scraper
if accept_scraper is None:
print("\n🛑 Kabul Scraper başlatılamadığı için program sonlandırılıyor.")
return
loaded_proxies = load_proxies_from_file(PROXY_FILE)
if not loaded_proxies:
print("\n🛑 Proxy yüklenemediği için worker'lar başlatılamıyor.")
return
print(f"\n🚀 {NUM_POLLING_WORKERS} adet sorgulama worker'ı ve durum güncelleyici başlatılıyor...")
tasks = []
for i in range(NUM_POLLING_WORKERS):
task = asyncio.create_task(poll_worker(i))
tasks.append(task)
status_task = asyncio.create_task(status_updater())
tasks.append(status_task)
print(f"\n✅ {len(tasks)} görev (worker + status) başarıyla oluşturuldu ve çalışıyor.")
print("-" * 35)
try:
await asyncio.gather(*tasks)
except asyncio.CancelledError:
print("\nℹ️ Görevler iptal edildi.")
except Exception as e:
print(f"\n❌ Ana görevde beklenmedik hata: {type(e).__name__} - {e}")
finally:
print("\n🛑 Program sonlandırılıyor.")
if __name__ == "__main__":
try:
asyncio.run(main())
except KeyboardInterrupt:
print("\nCTRL+C algılandı. Program kapatılıyor...")
except Exception as e:
print(f"\n❌ Program başlangıcında kritik hata: {e}") Python Hızlandırma
2
●92
- 10-04-2025, 23:31:38Üyeliği durdurulduMerhabalar hocalarım bir rezervasyon botum rezervasyonu tespiti çok hızlı ama kabul aşamasında çok geç kalıyor yardımcı olabilecek varmı acaba, Chatgpt ve gemini ile sağlıklı cevaplar alamadım ,
- 11-04-2025, 21:41:51Cursor ai (claude 3.7 -thinking on ) kullanılarak düzenlendi.
import asyncio import time import json import certifi import cloudscraper import random from fake_useragent import UserAgent import os from datetime import datetime # Hızlandırma için değişiklikler NUM_POLLING_WORKERS = 15 # 7'den 15'e çıkarıldı STATUS_UPDATE_INTERVAL = 1.0 # Console spam azaltıldı ACCEPT_RETRY_DELAY = 0.8 # 1.5'ten 0.8'e düşürüldü MAX_ACCEPT_RETRIES = 2 ACCEPT_TIMEOUT = 15 # 20'den 15'e düşürüldü MAX_CONCURRENT_ACCEPTS = 10 # Paralel kabul işlemi sayısı MAX_PREVIOUS_HASHES = 1000 # Önbellek sınırlandırması DEBUG_MODE = False # Loglama kontrolü ENABLE_TELEGRAM = True # Telegram bildirimleri açık/kapalı SSL_VERIFY = False # SSL doğrulamasını devre dışı bırak (hız için) BOOKING_URL = "api1" ACCEPT_URL = "api2" LOGIN_HASH = "hash1" ACCEPT_LOGIN_HASH = "hash2" VEHICLE_ID = "36979" TELEGRAM_BOT_TOKEN = "token" TELEGRAM_CHAT_ID = "id" PROXY_FILE = "proxy.txt" previous_hashes = set() lock = asyncio.Lock() success_count = 0 ua = UserAgent() loaded_proxies = [] accept_semaphore = asyncio.Semaphore(MAX_CONCURRENT_ACCEPTS) # Paralel kabul işlemleri için semafor try: accept_scraper = cloudscraper.create_scraper( browser={"browser": "chrome", "platform": "windows", "mobile": False}, pool_connections=20, # Bağlantı havuzu pool_maxsize=20 # Maksimum havuz boyutu ) print("\n<img draggable=\"false\" class=\"emoji\" alt=\"✅\" src=\"//cdn.r10.net/emojis/html/2705.png\"> Kabul istekleri için Cloudscraper başarıyla başlatıldı.") except Exception as e: print(f"\n<img draggable=\"false\" class=\"emoji\" alt=\"❌\" src=\"//cdn.r10.net/emojis/html/274c.png\"> Kabul istekleri için Cloudscraper başlatılamadı: {e}") accept_scraper = None # Hata durumunda None olarak ayarla # --------------------------------------------- # =================================== # FONKSİYONLAR # =================================== def get_current_time_ms(): return datetime.now().strftime('%H:%M:%S.%f')[:-3] def load_proxies_from_file(filename=PROXY_FILE): """proxy.txt dosyasından ip:port:user:pass formatındaki proxy'leri okur.""" proxies = [] if not os.path.exists(filename): print(f"\n<img draggable=\"false\" class=\"emoji\" alt=\"❌\" src=\"//cdn.r10.net/emojis/html/274c.png\"> HATA: Proxy dosyası bulunamadı: {filename}") return [] try: with open(filename, 'r') as f: for line_num, line in enumerate(f): line = line.strip() if not line or line.startswith('#'): continue parts = line.split(':') if len(parts) == 4: ip, port, username, password = parts # IPv6 adresleri için köşeli parantez kontrolü if ':' in ip and not (ip.startswith('[') and ip.endswith(']')): ip = f"[{ip}]" # Köşeli parantez ekle proxy_url = f"http://{username}:{password}@{ip}:{port}" proxy_dict = {"http": proxy_url, "https": proxy_url} proxies.append(proxy_dict) else: if DEBUG_MODE: print(f"\n<img draggable=\"false\" class=\"emoji\" alt=\"⚠️\" src=\"//cdn.r10.net/emojis/html/26a0.png\"> Uyarı: {filename} dosyasındaki {line_num+1}. satır geçersiz formatta: '{line}'. Format ip:port:user:pass olmalı.") except Exception as e: print(f"\n<img draggable=\"false\" class=\"emoji\" alt=\"❌\" src=\"//cdn.r10.net/emojis/html/274c.png\"> HATA: Proxy dosyası okunurken hata oluştu ({filename}): {e}") return [] if not proxies: print(f"\n<img draggable=\"false\" class=\"emoji\" alt=\"❌\" src=\"//cdn.r10.net/emojis/html/274c.png\"> HATA: {filename} dosyasından geçerli proxy yüklenemedi.") else: print(f"\n<img draggable=\"false\" class=\"emoji\" alt=\"✅\" src=\"//cdn.r10.net/emojis/html/2705.png\"> {len(proxies)} adet proxy başarıyla yüklendi: {filename}") return proxies # Yeni proxy hız testi fonksiyonu async def test_proxies_speed(): """Proxy'leri test eder ve hızlarına göre sıralar.""" if not loaded_proxies: print("\n<img draggable=\"false\" class=\"emoji\" alt=\"⚠️\" src=\"//cdn.r10.net/emojis/html/26a0.png\"> Proxy listesi boş, test yapılamıyor.") return print(f"\n<img draggable=\"false\" class=\"emoji\" alt=\"🔄\" src=\"//cdn.r10.net/emojis/html/1f504.png\"> {len(loaded_proxies)} adet proxy test ediliyor...") scraper = cloudscraper.create_scraper( browser={"browser": "chrome", "platform": "windows", "mobile": False} ) results = [] for i, proxy in enumerate(loaded_proxies): if i % 5 == 0: print(f" {i}/{len(loaded_proxies)} proxy test ediliyor...") start_time = time.time() try: # Test için basit bir GET isteği yapılıyor response = await asyncio.to_thread( scraper.get, "https://www.google.com", proxies=proxy, timeout=5, verify=SSL_VERIFY ) elapsed = time.time() - start_time if response.status_code == 200: results.append((proxy, elapsed)) except: # Başarısız proxy'ler listenin sonuna ekleniyor results.append((proxy, float('inf'))) # Hıza göre sırala - en hızlı önce results.sort(key=lambda x: x[1]) # Sonsuzluk olan başarısız proxy'leri listenin sonuna koy sorted_proxies = [r[0] for r in results if r[1] != float('inf')] failed_proxies = [r[0] for r in results if r[1] == float('inf')] sorted_proxies.extend(failed_proxies) global loaded_proxies loaded_proxies = sorted_proxies success_count = len(sorted_proxies) - len(failed_proxies) print(f"\n<img draggable=\"false\" class=\"emoji\" alt=\"✅\" src=\"//cdn.r10.net/emojis/html/2705.png\"> Proxy testi tamamlandı: {success_count} başarılı, {len(failed_proxies)} başarısız.") return sorted_proxies def get_random_headers(): """Rastgele User-Agent ile HTTP başlıkları oluşturur.""" return { "Content-Type": "application/json", "User-Agent": ua.random } # ========================================================== # === send_telegram_message (SSL Hatası için Düzeltildi) === # ========================================================== async def send_telegram_message(message): """Telegram'a asenkron olarak bildirim gönderir (SSL doğrulaması ile).""" if not ENABLE_TELEGRAM or not TELEGRAM_BOT_TOKEN or not TELEGRAM_CHAT_ID: # Telegram devre dışı veya bilgiler eksik return url = f"https://api.telegram.org/bot{TELEGRAM_BOT_TOKEN}/sendMessage" payload = {"chat_id": TELEGRAM_CHAT_ID, "text": message, "parse_mode": "Markdown"} sender_scraper = None try: # Telegram için ayrı, basit bir scraper kullan sender_scraper = cloudscraper.create_scraper() # Cloudscraper doğrudan async context manager desteklemez, to_thread kullanmak daha güvenli response = await asyncio.to_thread( sender_scraper.post, url, json=payload, timeout=10, # 15'ten 10'a düşürüldü verify=SSL_VERIFY # SSL doğrulaması ayarı ) if response.status_code != 200 and DEBUG_MODE: response_text = response.text print(f"\n[{get_current_time_ms()}] <img draggable=\"false\" class=\"emoji\" alt=\"❌\" src=\"//cdn.r10.net/emojis/html/274c.png\"> Telegram Hatası: {response.status_code} - {response_text[:200]}") except asyncio.TimeoutError: if DEBUG_MODE: print(f"\n[{get_current_time_ms()}] <img draggable=\"false\" class=\"emoji\" alt=\"⚠️\" src=\"//cdn.r10.net/emojis/html/26a0.png\"> Telegram Bağlantı Hatası: Zaman aşımı (Timeout)") except Exception as e: if DEBUG_MODE: print(f"\n[{get_current_time_ms()}] <img draggable=\"false\" class=\"emoji\" alt=\"⚠️\" src=\"//cdn.r10.net/emojis/html/26a0.png\"> Telegram Bağlantı Hatası: {type(e).__name__} - {e}") finally: if sender_scraper: pass # ========================================================== # === /send_telegram_message === # ========================================================== async def accept_booking(booking_hash): """Bir rezervasyonu PROXYSİZ olarak kabul etmeye çalışır (Geliştirilmiş Loglama ile).""" global previous_hashes global lock global accept_scraper # Global scraper'ı kullan # Paralel işlem sayısını sınırlama async with accept_semaphore: start_time_accept = get_current_time_ms() if accept_scraper is None: if DEBUG_MODE: print(f"\n[{start_time_accept}] <img draggable=\"false\" class=\"emoji\" alt=\"🚫\" src=\"//cdn.r10.net/emojis/html/1f6ab.png\"> Kabul Scraper başlatılamadığı için kabul işlemi yapılamıyor: {booking_hash}") return False # --- Hash Kontrolü (Kilitle) --- async with lock: # Önbellek sınırlaması if len(previous_hashes) >= MAX_PREVIOUS_HASHES: # En eski hashleri temizle (set olduğu için ilk elemanları) to_remove = list(previous_hashes)[:len(previous_hashes) // 4] # %25'ini temizle for old_hash in to_remove: previous_hashes.discard(old_hash) if booking_hash in previous_hashes: return False # Zaten işleniyorsa veya işlendiyse çık previous_hashes.add(booking_hash) # ----------------------------- if DEBUG_MODE: print(f"\n[{start_time_accept}] <img draggable=\"false\" class=\"emoji\" alt=\"🚀\" src=\"//cdn.r10.net/emojis/html/1f680.png\"> Kabul işlemi başlatıldı (PROXYSİZ): {booking_hash}") accept_payload = { "login_hash": ACCEPT_LOGIN_HASH, "booking_hash": booking_hash, "vehicle_id": VEHICLE_ID, "refuse": "accept" } headers = get_random_headers() for attempt in range(MAX_ACCEPT_RETRIES): current_time_attempt = get_current_time_ms() if DEBUG_MODE: print(f" [{current_time_attempt}] <img draggable=\"false\" class=\"emoji\" alt=\"➡️\" src=\"//cdn.r10.net/emojis/html/27a1.png\"> Kabul Denemesi {attempt + 1}/{MAX_ACCEPT_RETRIES} gönderiliyor: {booking_hash}") try: accept_response = await asyncio.to_thread( accept_scraper.post, # Global scraper'ı kullan ACCEPT_URL, headers=headers, json=accept_payload, verify=SSL_VERIFY, # SSL doğrulama ayarı timeout=ACCEPT_TIMEOUT # Ayarlanan timeout ) current_time_response = get_current_time_ms() response_text_snippet = accept_response.text[:200] if accept_response.text else "Yanıt yok" if accept_response.status_code == 200: print(f" [{current_time_response}] <img draggable=\"false\" class=\"emoji\" alt=\"✅\" src=\"//cdn.r10.net/emojis/html/2705.png\"> BAŞARILI KABUL! (PROXYSİZ) - Deneme {attempt + 1}: {booking_hash}") message = f"<img draggable=\"false\" class=\"emoji\" alt=\"✅\" src=\"//cdn.r10.net/emojis/html/2705.png\"> Rezervasyon Kabul Edildi!\n\nHash: `{booking_hash}`\nZaman: {current_time_response}\n\n<img draggable=\"false\" class=\"emoji\" alt=\"🔗\" src=\"//cdn.r10.net/emojis/html/1f517.png\"> [Detay](https://site.com/{booking_hash})" asyncio.create_task(send_telegram_message(message)) # Telegram'a gönder return True # Başarılı, fonksiyondan çık else: # --- Detaylı Hata Loglaması --- if DEBUG_MODE: print(f" [{current_time_response}] <img draggable=\"false\" class=\"emoji\" alt=\"❌\" src=\"//cdn.r10.net/emojis/html/274c.png\"> KABUL HATASI (PROXYSİZ) - Durum Kodu: {accept_response.status_code} - Deneme {attempt + 1}/{MAX_ACCEPT_RETRIES}") print(f" Yanıt Başlangıcı: {response_text_snippet}...") print(f" Hash: {booking_hash}") # ------------------------------ if 400 <= accept_response.status_code < 500: if DEBUG_MODE: print(f" [{current_time_response}] 🛑 4xx hatası alındı, tekrar denenmeyecek: {booking_hash}") return False # Tekrar deneme if attempt + 1 < MAX_ACCEPT_RETRIES: wait_time = ACCEPT_RETRY_DELAY * (2 ** attempt) # Exponential backoff if DEBUG_MODE: print(f" [{current_time_response}] <img draggable=\"false\" class=\"emoji\" alt=\"⏳\" src=\"//cdn.r10.net/emojis/html/23f3.png\"> {wait_time:.1f} sn bekleniyor...") await asyncio.sleep(wait_time) except Exception as e: current_time_exception = get_current_time_ms() # --- Detaylı İstisna Loglaması --- if DEBUG_MODE: print(f" [{current_time_exception}] <img draggable=\"false\" class=\"emoji\" alt=\"⚠️\" src=\"//cdn.r10.net/emojis/html/26a0.png\"> KABUL BAĞLANTI/İSTİSNA HATASI (PROXYSİZ) - Deneme {attempt + 1}/{MAX_ACCEPT_RETRIES}") print(f" Hata: {type(e).__name__} - {e}") print(f" Hash: {booking_hash}") # ------------------------------ if attempt + 1 < MAX_ACCEPT_RETRIES: wait_time = ACCEPT_RETRY_DELAY * (2 ** attempt) # Exponential backoff if DEBUG_MODE: print(f" [{current_time_exception}] <img draggable=\"false\" class=\"emoji\" alt=\"⏳\" src=\"//cdn.r10.net/emojis/html/23f3.png\"> {wait_time:.1f} sn bekleniyor...") await asyncio.sleep(wait_time) if DEBUG_MODE: final_fail_time = get_current_time_ms() print(f"\n[{final_fail_time}] <img draggable=\"false\" class=\"emoji\" alt=\"🚫\" src=\"//cdn.r10.net/emojis/html/1f6ab.png\"> KABUL BAŞARISIZ (PROXYSİZ) (Tüm denemeler bitti): {booking_hash}") return False # ============================================= # === check_new_bookings FONKSİYONU (await ile güncellendi) === # ============================================= async def check_new_bookings(response_text): """ API yanıtını kontrol eder ve yeni rezervasyonları kabul için İŞLEME ALIR. (await kullanıldığı için, bu fonksiyon içinde rezervasyonlar sırayla işlenir) """ try: data = json.loads(response_text) # Anahtar varlık kontrollerini artır if not isinstance(data, dict): return api_data = data.get("data") if not isinstance(api_data, dict): return current_bookings = api_data.get("bookings") if not isinstance(current_bookings, list): return except json.JSONDecodeError as e: if DEBUG_MODE: print(f"\n[{get_current_time_ms()}] <img draggable=\"false\" class=\"emoji\" alt=\"⚠️\" src=\"//cdn.r10.net/emojis/html/26a0.png\"> JSON Decode Hatası: {e} - Yanıt: {response_text[:100]}...") return except Exception as e: if DEBUG_MODE: print(f"\n[{get_current_time_ms()}] <img draggable=\"false\" class=\"emoji\" alt=\"❌\" src=\"//cdn.r10.net/emojis/html/274c.png\"> Beklenmedik Hata (check_new_bookings): {type(e).__name__} - {e}") return if current_bookings: current_time_check = get_current_time_ms() print(f"\n[{current_time_check}] Yeni rezervasyon(lar) bulundu ({len(current_bookings)} adet).") # Tüm rezervasyonları parallel olarak işle tasks = [] for booking in current_bookings: if isinstance(booking, dict) and "booking_hash_link" in booking: booking_hash = booking["booking_hash_link"] if DEBUG_MODE: print(f" -> [{get_current_time_ms()}] <img draggable=\"false\" class=\"emoji\" alt=\"✨\" src=\"//cdn.r10.net/emojis/html/2728.png\"> REZERVASYON: {booking_hash} -> Kabul işlemi başlatılıyor...") # Her booking için bir görev oluştur task = asyncio.create_task(accept_booking(booking_hash)) tasks.append(task) else: if DEBUG_MODE: print(f" -> [{get_current_time_ms()}] <img draggable=\"false\" class=\"emoji\" alt=\"⚠️\" src=\"//cdn.r10.net/emojis/html/26a0.png\"> Geçersiz rezervasyon verisi formatı atlandı: {booking}") # Tüm görevlerin tamamlanmasını bekle if tasks: await asyncio.gather(*tasks) if DEBUG_MODE: print(f"--- [{get_current_time_ms()}] Bulunan rezervasyonların işlenmesi tamamlandı (check_new_bookings). ---") # ============================================= # === /check_new_bookings FONKSİYONU === # ============================================= async def poll_worker(worker_id): global success_count global lock global loaded_proxies # Her worker için ayrı scraper instance worker_scraper = None # Başlangıçta None try: worker_scraper = cloudscraper.create_scraper( browser={"browser": "chrome", "platform": "windows", "mobile": False}, pool_connections=10, # Bağlantı havuzu pool_maxsize=10 # Maksimum havuz boyutu ) except Exception as e: print(f"[{get_current_time_ms()}] [Worker {worker_id}] <img draggable=\"false\" class=\"emoji\" alt=\"❌\" src=\"//cdn.r10.net/emojis/html/274c.png\"> Başlatılamadı: Scraper oluşturma hatası: {e}") return # Scraper oluşturulamazsa worker çalışamaz polling_interval = 0 # Başlangıçta bekleme yok MAX_POLL_RETRIES = 1 # Sorgu için tekrar deneme sayısı POLL_RETRY_DELAY = 0.5 # Sorgu tekrar deneme gecikmesi (1'den 0.5'e düşürüldü) while True: await asyncio.sleep(polling_interval) # Döngüler arası (varsa) bekleme if not loaded_proxies: await asyncio.sleep(5) continue # --- Proxy Seçimi ve İstek Hazırlığı --- try: proxies = random.choice(loaded_proxies[:len(loaded_proxies)//2 or 1]) # En hızlı proxy'lerden seç except IndexError: await asyncio.sleep(2.5) # 5'ten 2.5'e düşürüldü continue headers = get_random_headers() response = None # ------------------------------------ for attempt in range(MAX_POLL_RETRIES): try: payload = {"login_hash": LOGIN_HASH} response = await asyncio.to_thread( worker_scraper.post, BOOKING_URL, headers=headers, json=payload, verify=SSL_VERIFY, # SSL doğrulama ayarı proxies=proxies, timeout=10 # Sorgu timeout'u 15'ten 10'a düşürüldü ) if response.status_code == 200: async with lock: success_count += 1 response_text = response.text # Yeni rezervasyonları asenkron olarak kontrol et asyncio.create_task(check_new_bookings(response_text)) polling_interval = 0 # Başarılı ise hemen tekrar dene break # Başarılı, deneme döngüsünden çık else: if 400 <= response.status_code < 500: polling_interval = 0.25 # 0.5'ten 0.25'e düşürüldü break # if attempt + 1 < MAX_POLL_RETRIES: await asyncio.sleep(POLL_RETRY_DELAY * (2 ** attempt)) else: polling_interval = 0.25 # 0.5'ten 0.25'e düşürüldü except Exception as e: polling_interval = 0.25 # 0.5'ten 0.25'e düşürüldü if attempt + 1 < MAX_POLL_RETRIES: await asyncio.sleep(POLL_RETRY_DELAY * (2 ** attempt)) async def status_updater(): global success_count global lock last_print_time = time.monotonic() while True: await asyncio.sleep(max(0, STATUS_UPDATE_INTERVAL - (time.monotonic() - last_print_time))) last_print_time = time.monotonic() async with lock: current_count = success_count current_time_str = get_current_time_ms() print(f"\r<img draggable=\"false\" class=\"emoji\" alt=\"🔄\" src=\"//cdn.r10.net/emojis/html/1f504.png\"> Toplam Başarılı Sorgu: {current_count} | Zaman: {current_time_str} ", end="") # =================================== # ANA PROGRAM YÖNETİMİ # =================================== async def main(): """Worker ve status task'larını başlatır ve çalışmasını bekler.""" global loaded_proxies global accept_scraper if accept_scraper is None: print("\n🛑 Kabul Scraper başlatılamadığı için program sonlandırılıyor.") return loaded_proxies = load_proxies_from_file(PROXY_FILE) if not loaded_proxies: print("\n🛑 Proxy yüklenemediği için worker'lar başlatılamıyor.") return # Proxy hız testi print("\n<img draggable=\"false\" class=\"emoji\" alt=\"🔄\" src=\"//cdn.r10.net/emojis/html/1f504.png\"> Proxy'ler test ediliyor...") await test_proxies_speed() print(f"\n<img draggable=\"false\" class=\"emoji\" alt=\"🚀\" src=\"//cdn.r10.net/emojis/html/1f680.png\"> {NUM_POLLING_WORKERS} adet sorgulama worker'ı ve durum güncelleyici başlatılıyor...") tasks = [] for i in range(NUM_POLLING_WORKERS): task = asyncio.create_task(poll_worker(i)) tasks.append(task) status_task = asyncio.create_task(status_updater()) tasks.append(status_task) print(f"\n<img draggable=\"false\" class=\"emoji\" alt=\"✅\" src=\"//cdn.r10.net/emojis/html/2705.png\"> {len(tasks)} görev (worker + status) başarıyla oluşturuldu ve çalışıyor.") print("-" * 35) try: await asyncio.gather(*tasks) except asyncio.CancelledError: print("\n<img draggable=\"false\" class=\"emoji\" alt=\"ℹ\" src=\"//cdn.r10.net/emojis/html/2139.png\">️ Görevler iptal edildi.") except Exception as e: print(f"\n<img draggable=\"false\" class=\"emoji\" alt=\"❌\" src=\"//cdn.r10.net/emojis/html/274c.png\"> Ana görevde beklenmedik hata: {type(e).__name__} - {e}") finally: print("\n🛑 Program sonlandırılıyor.") if __name__ == "__main__": try: asyncio.run(main()) except KeyboardInterrupt: print("\nCTRL+C algılandı. Program kapatılıyor...") except Exception as e: print(f"\n<img draggable=\"false\" class=\"emoji\" alt=\"❌\" src=\"//cdn.r10.net/emojis/html/274c.png\"> Program başlangıcında kritik hata: {e}")
Başaracaksın biraz daha teknik detayları düşün. Kurgula.