Initial commit: добавление проекта predictV1
Включает модели ML для предсказаний, API маршруты, скрипты обучения и данные. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
106
start/parse_pro_details_match.py
Normal file
106
start/parse_pro_details_match.py
Normal file
@@ -0,0 +1,106 @@
|
||||
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("Завершено сохранение деталей матчей")
|
||||
79
start/parse_pro_matches.py
Normal file
79
start/parse_pro_matches.py
Normal file
@@ -0,0 +1,79 @@
|
||||
import requests
|
||||
import psycopg2
|
||||
from psycopg2.extras import execute_values
|
||||
|
||||
PAGE = 10
|
||||
url = "https://api.opendota.com/api/proMatches"
|
||||
all_matches = []
|
||||
less_than_match_id = None
|
||||
|
||||
# Разрешенные лиги
|
||||
ALLOWED_LEAGUES = [17420] # Замените на нужные ID лиг
|
||||
|
||||
for page in range(PAGE):
|
||||
params = {}
|
||||
if less_than_match_id:
|
||||
params['less_than_match_id'] = less_than_match_id
|
||||
|
||||
response = requests.get(url, params=params)
|
||||
|
||||
if response.status_code == 200:
|
||||
matches = response.json()
|
||||
all_matches.extend(matches)
|
||||
print(f"Страница {page + 1}: получено {len(matches)} матчей")
|
||||
|
||||
if matches:
|
||||
less_than_match_id = matches[-1]['match_id']
|
||||
else:
|
||||
print(f"Ошибка на странице {page + 1}: {response.status_code}")
|
||||
break
|
||||
|
||||
print(f"\nВсего получено {len(all_matches)} матчей")
|
||||
|
||||
# Подключение к базе данных
|
||||
conn = psycopg2.connect(
|
||||
host="localhost",
|
||||
port=5432,
|
||||
database="korobka_db",
|
||||
user="postgres",
|
||||
password="postgres"
|
||||
)
|
||||
cursor = conn.cursor()
|
||||
|
||||
# Подготовка данных для вставки (фильтр по leagueid)
|
||||
data = [
|
||||
(
|
||||
match['match_id'],
|
||||
match.get('start_time'),
|
||||
match.get('leagueid'),
|
||||
match.get('radiant_team_id'),
|
||||
match.get('dire_team_id'),
|
||||
match.get('radiant_win'),
|
||||
'pro' # ← добавили source
|
||||
)
|
||||
for match in all_matches
|
||||
if match.get('leagueid') in ALLOWED_LEAGUES
|
||||
]
|
||||
|
||||
print(f"Отфильтровано {len(data)} матчей из {len(all_matches)} по разрешенным лигам")
|
||||
|
||||
# Вставка данных в таблицу
|
||||
execute_values(
|
||||
cursor,
|
||||
"""INSERT INTO matches (id, start_time, leagueid, radiant_team_id, dire_team_id, radiant_win, source)
|
||||
VALUES %s
|
||||
ON CONFLICT (id) DO UPDATE SET
|
||||
start_time = EXCLUDED.start_time,
|
||||
leagueid = EXCLUDED.leagueid,
|
||||
radiant_team_id = EXCLUDED.radiant_team_id,
|
||||
dire_team_id = EXCLUDED.dire_team_id,
|
||||
radiant_win = EXCLUDED.radiant_win,
|
||||
source = EXCLUDED.source""",
|
||||
data
|
||||
)
|
||||
|
||||
conn.commit()
|
||||
cursor.close()
|
||||
conn.close()
|
||||
|
||||
print(f"Успешно сохранено {len(data)} матчей в БД")
|
||||
Reference in New Issue
Block a user