본문 바로가기
프로젝트/진행중

Project_LOL / 게임 승패 예측 (1)

by 가장따뜻한로봇 2023. 6. 1.

리그 오브 레전드(이하 롤)라는 게임은 여러가지 모드가 있는데, 그 중 남들과 경쟁하는 '랭크' 게임 중 솔로 랭크에서의 승률을 예측해 보고자 함.

 

https://developer.riotgames.com/

 

Riot Developer Portal

About the Riot Games API With this site we hope to provide the League of Legends developer community with access to game data in a secure and reliable way. This is just part of our ongoing effort to respond to players' and developers' requests for data and

developer.riotgames.com

 

개인 개발용으로는 무료로 사용 가능함.(호출 제한, 1초 마다 20개,  2분마다 100개씩)

RATE LIMITS

20 requests every 1 seconds(s)
100 requests every 2 minutes(s)

 

롤 api 중 MATCH-V5 를 이용하여 경기 데이터를 가져올수 있음.

데이터의 "queueId" 부분이 420 이면 솔로 랭크로 확인되지만

호출이 2분에 200번이라는 제한이 있어 시간이 많이 걸려 다른 방식으로 변경

 

LEAGUE-V4 를 이용하여 마스터 리그의 유저 데이터를 불러와 각 유저들이 플레이한 솔로 랭크 경기를 가져오기로 결정.

 

 

import requests
import json
import time
import pandas as pd
from tqdm import tqdm
import pickle
from datetime import datetime
import key # API key 를 key라는 파일에 저장후 불러 오는 방법으로 사용

api_key = key.lol_api


# MATCH-V5 에서 유저가 한 경기를 검색할려면 puuid 라는게 필요. 그것을 찾기 위해 summoner id 를 이용
# 결과는 summoner id => puuid => match id 순으로 데이터를 가져오게 됨


# 1-1. 마스터 등급 솔로 랭크 게임을 플레이한 플레이어의 summoner id 

url = 'https://kr.api.riotgames.com/lol/league/v4/masterleagues/by-queue/RANKED_SOLO_5x5?api_key=' + api_key

summoner = pd.DataFrame(columns = ['summonerName','summonerId','leaguePoints'])

rq = requests.get(url)

for i in rq.json()['entries']:
    summoner.loc[len(summoner)] = i['summonerName'], i['summonerId'] , i['leaguePoints']

print(len(summoner)) # 0522 05:47 기준 (시간에 따라 사람들의 랭크가 바뀜)



# 1-2. summonerId를 통해 puuid 추출

df_puuid = pd.DataFrame(columns = ['name','puuid','leaguePoints'])

for i in tqdm(range(len(summoner))):
    url = 'https://kr.api.riotgames.com/lol/summoner/v4/summoners/' + summoner['summonerId'][i] + '?api_key=' + api_key
    r = requests.get(url)
    time.sleep(0.95) # 2분에 100요청이 넘지 않게 쉬는 시간 설정

    if r.status_code == 200: # request 정상 호출
        df_puuid.loc[len(df_puuid)] = r.json()['name'], r.json()['puuid'] , summoner['leaguePoints'][i]
    
    elif r.status_code == 429: # 2분당 100요청 한계
        start_time = time.time()
        
        while True:
            if r.status_code == 429:
                time.sleep(120)
                r = requests.get(url)
            elif r.status_code == 200:
                print('total wait time : ', time.time() - start_time)
                df_puuid.loc[len(df_puuid)] = r.json()['name'], r.json()['puuid'] , summoner['leaguePoints'][i]
                break
            else:
                print("에러") # 다른 에러가 날 경우 정지
                break
    else:
        print("에러") # 다른 에러가 날 경우 정지
        break
        
df_puuid.to_csv('./summoner_0522.csv',index=False, encoding='utf-8-sig')
len(df_puuid)

puuid

 

 

롤의 메타가 바뀌는 패치가 최근에 있었음.

점검 완료 시간은 2023년 5월 18일(목) 06:56 서버 점검 및 업데이트 완료.

따라서 시작 시간은 2023년 5월 18일 07.00 부터 summoner id 추출 시간인 2023년 5월 22일 05:47까지

https://www.leagueoflegends.com/ko-kr/news/announcements/20230518-deploy/

 

2023년 5월 18일 (목) 서버 점검 및 업데이트 안내 (완료) - 리그 오브 레전드

2023년 5월 18일 (목) 서버 점검 및 업데이트 안내 드립니다.

www.leagueoflegends.com

 

#1-3. 패치 이후 플레이한 최대 100개 게임의 match id 추출하기
matchId = []
count = 100 #count의 숫자를 바꾸면 경기 수가 달라집니다 최대 100
start_date = int(datetime(2023, 5, 18, 7, 0, 0).timestamp()) # 점검 일시 : 2023년 5월 18일 (목) (06:56 점검 완료)
end_date = int(datetime(2023, 5, 22, 5, 47, 0).timestamp()) # 마스터리그 목록 추출 시간
for i in tqdm(df_puuid['puuid']):
    url_match = "https://asia.api.riotgames.com/lol/match/v5/matches/by-puuid/"+ i + f"/ids?startTime={start_date}&endTime={end_date}&type=ranked&start=0&count={count}&api_key=" + api_key
    r_match = requests.get(url_match)

    if r_match.status_code == 200:
        matchId.extend(r_match.json())
    elif r_match.status_code == 429:
        start_time = time.time()
        
        while True:
            if r_match.status_code == 429:
                time.sleep(120)
                r_match = requests.get(url_match)
                print(r_match.status_code)

            elif r_match.status_code == 200:
                print('total wait time : ', time.time() - start_time)
                matchId.extend(r_match.json())
                break
            else:
                print("에러")
                break
    else:
        print(r_match.status_code,"에러")
        break

# 중복 제거
match_list = list(set(matchId))
print(len(match_list))

# match list 를 pickle 로 저장.
with open('match_list.pickle', 'wb') as f:
    pickle.dump(match_list, f)

총 41068개의 게임.

# match list load (이어서 하면 불러오지 않아도 됨)
with open('match_list.pickle', 'rb') as f:
    match_list = pickle.load(f)

MATCH-V5 에서 확인 결과 matchdata 와 bandata 두 개를 추출하면 될 것 같음.

( matchdata : 게임의 전체적인 정보,  bandata : 게임 시작 시 픽벤창에서 일어나는 일)

# 1-4. 게임별 필요한 데이터 추출하여 JSON으로 저장

matchdata = {}
bandata = {}

for i in tqdm(match_list):

    url4 = 'https://asia.api.riotgames.com/lol/match/v5/matches/' + str(i) +'?api_key=' + api_key
    r = requests.get(url4)
    time.sleep(0.95)

    if r.status_code == 200: 
        matchdata[i] = r.json()['info']['participants']
        bandata[i] = r.json()['info']['teams']

    elif r.status_code == 429:
        start_time = time.time()

        while True: 
            if r.status_code == 429:
                time.sleep(120)
                r = requests.get(url4)
            elif r.status_code == 200: 
                print('total wait time : ', time.time() - start_time)
                matchdata[i] = r.json()['info']['participants']
                bandata[i] = r.json()['info']['teams']
                break
            else:
                print("에러")
                break
    else:
        print("기타 에러",r.status_code)
        break
        
with open('./matchdata_0522.json','w') as f:
    json.dump(matchdata, f, ensure_ascii=False, indent=4)
#한글 때문에 ensure_ascii=False 로 설정
#혹시 파이썬으로 작업 할지도 몰라서 파이썬 관례상 들여쓰기 4
#들여쓰기를 하면 저장시 용량이 늘어남

with open('./bandata_0522.json','w') as f:
    json.dump(bandata, f, ensure_ascii=False, indent=4)

 

 

'프로젝트 > 진행중' 카테고리의 다른 글

Project_LOL / 게임 승패 예측 (3)  (2) 2023.06.01
Project_LOL / 게임 승패 예측 (2)  (1) 2023.06.01