commit
This commit is contained in:
@@ -23,7 +23,7 @@
|
|||||||
"debug": {
|
"debug": {
|
||||||
"bleu~~": 1
|
"bleu~~": 1
|
||||||
},
|
},
|
||||||
"actual_at": 1774695578,
|
"actual_at": 1774697272,
|
||||||
"groups": {
|
"groups": {
|
||||||
"ТВБ-164": {
|
"ТВБ-164": {
|
||||||
"name": "ТВБ-164",
|
"name": "ТВБ-164",
|
||||||
|
|||||||
39
main.py
39
main.py
@@ -10,6 +10,8 @@ from datetime import datetime
|
|||||||
|
|
||||||
from fastapi import FastAPI
|
from fastapi import FastAPI
|
||||||
from fastapi.responses import FileResponse
|
from fastapi.responses import FileResponse
|
||||||
|
from requests.adapters import HTTPAdapter
|
||||||
|
from urllib3 import Retry
|
||||||
import uvicorn
|
import uvicorn
|
||||||
|
|
||||||
# --- Загрузка переменных окружения ---
|
# --- Загрузка переменных окружения ---
|
||||||
@@ -130,6 +132,41 @@ def ask_gemini(unknown_raws):
|
|||||||
|
|
||||||
return results
|
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():
|
def job_iteration():
|
||||||
log("--- Начало итерации обновления расписания ---")
|
log("--- Начало итерации обновления расписания ---")
|
||||||
cache = load_json(FILE_CACHE, {})
|
cache = load_json(FILE_CACHE, {})
|
||||||
@@ -137,7 +174,7 @@ def job_iteration():
|
|||||||
# ШАГ 1: Единоразовая загрузка монолита
|
# ШАГ 1: Единоразовая загрузка монолита
|
||||||
log(f"[*] Скачивание all-in-one файла {URL_RESULT_V2} ...")
|
log(f"[*] Скачивание all-in-one файла {URL_RESULT_V2} ...")
|
||||||
try:
|
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:
|
except Exception as e:
|
||||||
log(f"[!!!] Ошибка скачивания базового файла расписаний: {e}")
|
log(f"[!!!] Ошибка скачивания базового файла расписаний: {e}")
|
||||||
return
|
return
|
||||||
|
|||||||
Reference in New Issue
Block a user