import requests import psycopg2 import time from psycopg2.extras import RealDictCursor, execute_values # Подключение к базе данных conn = psycopg2.connect( host="localhost", port=5432, database="korobka_db", user="postgres", password="postgres" ) cursor = conn.cursor(cursor_factory=RealDictCursor) # Функция для определения позиции по lane и lane_role def get_position(lane, lane_role): """ lane 2, lane_role 2 -> pos 2 (Mid Core) lane 1, lane_role 1 -> pos 1 (Safe Lane Carry) lane 1, lane_role 3 -> pos 5 (Safe Lane Support) lane 3, lane_role 1 -> pos 3 (Offlane Core) lane 3, lane_role 3 -> pos 4 (Offlane Support) """ if lane == 2 and lane_role == 2: return 2 elif lane == 1 and lane_role == 1: return 1 elif lane == 1 and lane_role == 3: return 5 elif lane == 3 and lane_role == 1: return 3 elif lane == 3 and lane_role == 3: return 4 else: return -1 # Неизвестная комбинация # Получение ID матчей из БД cursor.execute(""" select m.id from matches m left join details_match dm on dm.match_id = m.id where m."source" = 'pro' and dm.match_id is null """) matches = cursor.fetchall() match_ids = [match['id'] for match in matches] print(f"Получено {len(match_ids)} ID матчей из БД") # Запрос деталей для каждого матча for idx, match_id in enumerate(match_ids, 1): url = f"https://api.opendota.com/api/matches/{match_id}" try: response = requests.get(url, timeout=30) if response.status_code == 200: match_data = response.json() picks_bans = match_data.get('picks_bans', []) players = match_data.get('players', []) print(f"[{idx}/{len(match_ids)}] Match {match_id}: {len(picks_bans)} picks/bans, {len(players)} players") # Создаем словари из players hero_to_account = {player.get('hero_id'): player.get('account_id') for player in players if player.get('hero_id')} hero_to_pos = {player.get('hero_id'): get_position(player.get('lane'), player.get('lane_role')) for player in players if player.get('hero_id')} # Сохранение picks_bans в БД (только пики) с позициями data = [ ( match_id, pick_ban.get('hero_id'), pick_ban.get('team'), pick_ban.get('order'), hero_to_account.get(pick_ban.get('hero_id')), # players_id hero_to_pos.get(pick_ban.get('hero_id'), -1), # pos 'pro' # source ) for pick_ban in picks_bans if pick_ban.get('is_pick') ] print(f"Вставка {len(data)} записей для матча {match_id}") execute_values( cursor, """INSERT INTO details_match (match_id, hero_id, team, "order", players_id, pos, source) VALUES %s""", data ) conn.commit() time.sleep(1) # пауза между запросами else: print(f"[{idx}/{len(match_ids)}] Ошибка для матча {match_id}: {response.status_code}") if response.status_code == 429: print("Превышен лимит запросов, ждем 10 секунд...") time.sleep(10) except Exception as e: print(f"[{idx}/{len(match_ids)}] Исключение для матча {match_id}: {e}") cursor.close() conn.close() print("Завершено сохранение деталей матчей")