diff --git a/data/result.json b/data/result.json index f2645e3..7058bb9 100644 --- a/data/result.json +++ b/data/result.json @@ -23,7 +23,7 @@ "debug": { "bleu~~": 1 }, - "actual_at": 1774695578, + "actual_at": 1774697272, "groups": { "ТВБ-164": { "name": "ТВБ-164", diff --git a/main.py b/main.py index b79ece1..a7844e3 100644 --- a/main.py +++ b/main.py @@ -10,6 +10,8 @@ from datetime import datetime from fastapi import FastAPI from fastapi.responses import FileResponse +from requests.adapters import HTTPAdapter +from urllib3 import Retry import uvicorn # --- Загрузка переменных окружения --- @@ -130,6 +132,41 @@ def ask_gemini(unknown_raws): return results +def fetch_json_robust(url, timeout=120): + """ + Устойчивый HTTP-клиент с маскировкой под браузер и механизмом Retry. + Адаптирован для обхода базовых проверок Cloudflare. + """ + session = requests.Session() + + # Маскировка под стандартный браузер + session.headers.update({ + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36", + "Accept": "application/json", + "Accept-Encoding": "gzip, deflate", # Оптимизация получения 2.4 МБ + "Connection": "keep-alive" + }) + + # Настройка стратегии повторных попыток + # 3 попытки, задержки: 2с, 4с, 8с. Отработка ошибок таймаутов Cloudflare (522, 524) + retry_strategy = Retry( + total=3, + backoff_factor=2, + status_forcelist=[429, 500, 502, 503, 504, 522, 524], + allowed_methods=["GET"] + ) + + adapter = HTTPAdapter(max_retries=retry_strategy) + session.mount("http://", adapter) + session.mount("https://", adapter) + + proxies = {"http": PROXY_URL, "https": PROXY_URL} if PROXY_URL else None + + response = session.get(url, timeout=timeout, proxies=proxies) + response.raise_for_status() + + return response.json() + def job_iteration(): log("--- Начало итерации обновления расписания ---") cache = load_json(FILE_CACHE, {}) @@ -137,7 +174,7 @@ def job_iteration(): # ШАГ 1: Единоразовая загрузка монолита log(f"[*] Скачивание all-in-one файла {URL_RESULT_V2} ...") try: - v2_data = requests.get(URL_RESULT_V2, timeout=60).json() + v2_data = fetch_json_robust(URL_RESULT_V2, timeout=120) except Exception as e: log(f"[!!!] Ошибка скачивания базового файла расписаний: {e}") return