본문 바로가기

[Riot API] 매치 데이터 1. 랭크 게임 개인과 팀의 플레이 정보

Python/API by Mandarim_ 2024. 8. 12.

 

이 전 게시글에서 기본적으로 라이엇 API 사용법을 시작으로 소환사의 정보 등을 가져오는 방법을 작성했다.

이번 게시글에서는 지난번에 다루지 못한 매치데이터를 활용하는 방법 중 상대방과의 성장차이를 수집하도록 하겠다.

 

먼저 분석할 대상인 "96년생 티모장인#9202"님의 기본적인 플레이어 정보를 가지고 와야 한다.

(지난 게시글에서 다루었으니 코드만 간단히 공유)

더보기

 1. 기본적인 정보 불러오기.

import requests
import json
from urllib import parse # 한글

api_key = # 본인의 API KEY 입력
REQUEST_HEADERS = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36",
    "Accept-Language": "ko-KR,ko;q=0.9,en-US;q=0.8,en;q=0.7",
    "Accept-Charset": "application/x-www-form-urlencoded; charset=UTF-8",
    "Origin": "https://developer.riotgames.com",
    "X-Riot-Token": api_key
}

userNickname="96년생 티모장인"
tagLine="9202"
encodedName = parse.quote(userNickname)
print(encodedName)
url = f"https://asia.api.riotgames.com/riot/account/v1/accounts/by-riot-id/{encodedName}/{tagLine}"

player_id = requests.get(url, headers=REQUEST_HEADERS).json()
puuid = player_id['puuid']
player = requests.get(f"https://kr.api.riotgames.com/lol/summoner/v4/summoners/by-puuid/{puuid}", headers=REQUEST_HEADERS).json()

playerInfo = requests.get("https://kr.api.riotgames.com/lol/league/v4/entries/by-summoner/"+player['id'], headers = REQUEST_HEADERS).json();

 

2. game 고유이름 불러오기

n_wins = playerInfo[0]['wins']
n_losses = playerInfo[0]['losses']
n_total = n_wins + n_losses;
print(n_wins); print(n_losses); print(n_total)

r = n_total // 100
other = n_total % 100

all_gamesID = []
for i in range(r+1):
  start = i*100
  if i != r :
    tmp_gamesID = requests.get(f"https://asia.api.riotgames.com/lol/match/v5/matches/by-puuid/{player['puuid']}/ids?type=ranked&start={start}&count={100}", headers = REQUEST_HEADERS).json();
  else :
    tmp_gamesID = requests.get(f"https://asia.api.riotgames.com/lol/match/v5/matches/by-puuid/{player['puuid']}/ids?type=ranked&start={start}&count={other}", headers = REQUEST_HEADERS).json();

  all_gamesID.extend(tmp_gamesID)

 

0. 매치 데이터 구조 파악하기

 

매치 데이터의 구조는 다음과 같다.

모두 Dictionary 형태로 기록되어 있으며 Info 데이터 안에 플레이어 10명의 요약된 인게임 정보가 기록되어 있다.

매치데이터 구조

각 데이터베이스 속에 변수는 너무 방대해서 어떤 변수가 있는진 라이엇 홈페이지에서 직접 확인해 보는 게 좋다.

요약하자면, 필요한 정보는 아래처럼 확인할 수 있다.

  •  각 게임의 기본 정보를 얻고 싶다면 Match - Metadata
  •  각 플레이어의 기본 정보를 얻고 싶다면 Match - Info - Participants 
  •  각 플레이어의 특정 상황에서 성과 정보를 얻고 싶다면 Match - Info - Participants - Challenges (NA 많음)
  •  각 팀의 정보를 얻고 싶다면 Match - Info - Team 

 

1. 작성 코드와 설명

Analysis_gameID = []
Analysis_df = pd.DataFrame()

for i in range(len(all_gamesID):
  id = all_gamesID[i]
  if i % 100 == 1:
    print(i)
  
  # 시간당 API 호출할 수 있는 제한을 넘겼을 때 대비
  try:
    gameInfo = requests.get("https://asia.api.riotgames.com/lol/match/v5/matches/"+id, headers = REQUEST_HEADERS).json();
    PlayedMin = gameInfo['info']['gameDuration'] / 60
  except:
    time.sleep(121)
    gameInfo = requests.get("https://asia.api.riotgames.com/lol/match/v5/matches/"+id, headers = REQUEST_HEADERS).json();
    PlayedMin = gameInfo['info']['gameDuration'] / 60
	
  # 경쟁전의 경우 "CLASSIC".
  if gameInfo['info']['gameMode'] != 'CLASSIC':
    print(gameInfo['info']['gameMode'])
    continue;
  if gameInfo['info']['participants']==[] :
    print(gameInfo['info']['gameMode'])
    continue;

  # Game의 기본 정보 기록.
  UnixTime = gameInfo['info']['gameStartTimestamp'] # Unix Time
  Participants = gameInfo['metadata']['participants'] # 참가자 puuid 모두
  gameVersion = gameInfo['info']['gameVersion'] # Game Version
  mapID = gameInfo['info']['mapId'] # Map Version
  gameMode = gameInfo['info']['gameMode'] # Game Mode

  # Participants에 기록된 10명 중 '96년생 티모장인'을 중심으로 데이터 수집하고자 함.
  for j in range(10) :
  	# 이 때 participants 중 puuid가 같은 사람을 기준으로 찾는다.
    if gameInfo['info']['participants'][j]['puuid'] == player['puuid'] :
      TOPpartID = gameInfo['info']['participants'][j]['participantId']
      Position = gameInfo['info']['participants'][j]['teamPosition']
      ChampID = gameInfo['info']['participants'][j]['championId']
      ChampName = gameInfo['info']['participants'][j]['championName']
      Win = gameInfo['info']['participants'][j]['win']
      TeamID = gameInfo['info']['participants'][j]['teamId']
      level = gameInfo['info']['participants'][j]['champLevel']
      Exp = gameInfo['info']['participants'][j]['champExperience']


      # K/D/A info
      N_assists = gameInfo['info']['participants'][j]['assists']
      N_deaths = gameInfo['info']['participants'][j]['deaths']
      N_kills = gameInfo['info']['participants'][j]['kills']
      N_QuickSoloKills = gameInfo['info']['participants'][j]['challenges']['quickSoloKills']
      FirstBloodKill = gameInfo['info']['participants'][j]['firstBloodKill']
      FirstBloodAssist = gameInfo['info']['participants'][j]['firstBloodAssist']
      LongestTimeSpentLiving = gameInfo['info']['participants'][j]['longestTimeSpentLiving']
      TotalTimeSpentDead = gameInfo['info']['participants'][j]['totalTimeSpentDead']
      N_Minions = gameInfo['info']['participants'][j]['totalMinionsKilled']

      # challenges: 특정 상황에 대한 정보를 담고 있다.
      N_SoloKills = gameInfo['info']['participants'][j]['challenges']['soloKills'] # 팀의 어시스트 없이 혼자 잡은 킬
      N_Kill_UnderOwnTurret = gameInfo['info']['participants'][j]['challenges']['killsUnderOwnTurret'] # 역다이브 킬
      N_Kill_UnderEnemyTurret = gameInfo['info']['participants'][j]['challenges']['killsNearEnemyTurret'] # 다이브 킬
      N_KDA = gameInfo['info']['participants'][j]['challenges']['kda'] # 해당 게임에서의 KDA
      N_BountyGold = gameInfo['info']['participants'][j]['challenges']['bountyGold'] # 현상금 금액
      N_BountyLevel = gameInfo['info']['participants'][j]['bountyLevel'] # 현상금 (레벨) -- 인게임에선 확인불가
      N_Ability = gameInfo['info']['participants'][j]['challenges']['abilityUses'] # 스킬 사용 횟수
      
      # Dodged -- 스킬 피한 횟수
      N_SkillDodge = gameInfo['info']['participants'][j]['challenges']['skillshotsDodged']
      N_SkillDodge_SmallWindow = gameInfo['info']['participants'][j]['challenges']['dodgeSkillShotsSmallWindow']

      # Wards 
      Score_Vision = gameInfo['info']['participants'][j]['visionScore']
      
      N_ControlWards = gameInfo['info']['participants'][j]['challenges']['controlWardsPlaced']
      DetectorWardsPlaced = gameInfo['info']['participants'][j]['detectorWardsPlaced']
      WardsBought = gameInfo['info']['participants'][j]['sightWardsBoughtInGame']
      WardsPlaced = gameInfo['info']['participants'][j]['wardsPlaced']
      WardsKilled = gameInfo['info']['participants'][j]['wardsKilled']

      # Pings
      N_AssistMePings = gameInfo['info']['participants'][j]['assistMePings']
      N_CommandPings = gameInfo['info']['participants'][j]['commandPings']
      N_DangerPings = gameInfo['info']['participants'][j]['dangerPings']
      N_EnemyMissingPings = gameInfo['info']['participants'][j]['enemyMissingPings']
      N_GetBackPings = gameInfo['info']['participants'][j]['getBackPings']
      N_OnMyWayPings = gameInfo['info']['participants'][j]['onMyWayPings']
      N_PushPings = gameInfo['info']['participants'][j]['pushPings']

      # DMG to Building (억제기, 타워 등 포함) Turret (타워만), Objectives (정글몹?), Champions
      DMGToBuildings = gameInfo['info']['participants'][j]['damageDealtToBuildings']
      DMGToObjectives = gameInfo['info']['participants'][j]['damageDealtToObjectives']
      DMGToTurrets = gameInfo['info']['participants'][j]['damageDealtToTurrets']
      TotalDMG = gameInfo['info']['participants'][j]['totalDamageDealtToChampions']
      TotalTakenDMG = gameInfo['info']['participants'][j]['totalDamageTaken']
      
      FirstTowerAssist = gameInfo['info']['participants'][j]['turretKills']
      FirstTowerKill = gameInfo['info']['participants'][j]['turretTakedowns']
      TurretsLost = gameInfo['info']['participants'][j]['turretsLost']

      # Item: 사용자의 Item 수집,
      # 본 분석의 경우 주로 '티모'를 플레이하기 때문에 관련 아이템 위주로 수집함.
      items = [ gameInfo['info']['participants'][j]['item0'],
                gameInfo['info']['participants'][j]['item1'],
                gameInfo['info']['participants'][j]['item2'],
                gameInfo['info']['participants'][j]['item3'],
                gameInfo['info']['participants'][j]['item4'],
                gameInfo['info']['participants'][j]['item5'],
                gameInfo['info']['participants'][j]['item6'] ]

      Item_Malignance = 0 # 3118
      Item_Liandry = 0 # 6653
      Item_Rabadon = 0 # 3089
      Item_Nashor = 0 # 3115
      Item_Shadowflame = 0 # 4645
      Item_Void = 0; # 3135
      Item_Cryptbloom = 0; # 3137

      if 3118 in items:
        Item_Malignance += 1
      if 6653 in items:
        Item_Liandry += 1
      if 3089 in items:
        Item_Rabadon += 1
      if 3115 in items:
        Item_Nashor += 1
      if 3135 in items:
        Item_Void += 1
      if 3137 in items:
        Item_Cryptbloom += 1
		
      # Gold
      GoldEarned = gameInfo['info']['participants'][j]['goldEarned']
      GoldSpent = gameInfo['info']['participants'][j]['goldSpent']
	
      # 메인 룬 (=perk)
      PrimaryPerk = gameInfo['info']['participants'][j]['perks']['styles'][0]['selections'][0]['perk']
      
      # Nexus
      N_NexusKills = gameInfo['info']['participants'][j]['nexusKills']
      N_NexusLost = gameInfo['info']['participants'][j]['nexusLost']
      N_NexusTakeDowns = gameInfo['info']['participants'][j]['nexusTakedowns']

  for j in range(2) :
  	# 96년생 티모장인의 팀 정보 가져오기
    if gameInfo['info']['teams'][j]['teamId'] == TeamID :
      # Objective information
      TeamBaron_First = gameInfo['info']['teams'][j]['objectives']['baron']['first']
      TeamBaron_NKills = gameInfo['info']['teams'][j]['objectives']['baron']['kills']
      TeamChamp_First = gameInfo['info']['teams'][j]['objectives']['champion']['first']
      TeamChamp_NKills = gameInfo['info']['teams'][j]['objectives']['champion']['kills']
      TeamDragon_First = gameInfo['info']['teams'][j]['objectives']['dragon']['first']
      TeamDragon_NKills = gameInfo['info']['teams'][j]['objectives']['dragon']['kills']

      TeamHorde_NKills = gameInfo['info']['teams'][j]['objectives']['horde']['kills']
      TeamInhibior_First = gameInfo['info']['teams'][j]['objectives']['inhibitor']['first']
      TeamInhibior_Kills = gameInfo['info']['teams'][j]['objectives']['inhibitor']['kills']
      TeamRiftHerald_Kills = gameInfo['info']['teams'][j]['objectives']['riftHerald']['kills']
      TeamTower_First = gameInfo['info']['teams'][j]['objectives']['tower']['first']
      TeamTower_Kills = gameInfo['info']['teams'][j]['objectives']['tower']['kills']

      # Pick Information
      # '96년생 티모장인'이 밴했는지 알려면 복잡해서 우선 팀의 밴으로 정의함
      BanChamps = [gameInfo['info']['teams'][j]['bans'][0]['championId'],
                  gameInfo['info']['teams'][j]['bans'][1]['championId'],
                  gameInfo['info']['teams'][j]['bans'][2]['championId'],
                  gameInfo['info']['teams'][j]['bans'][3]['championId'],
                  gameInfo['info']['teams'][j]['bans'][4]['championId']]

      Ban_Jayce = 0
      Ban_TwistedFate = 0
      Ban_Cassiopeia = 0
      Ban_Jax = 0
      Ban_Skarner = 0
      Ban_Rumble = 0
      Ban_Ryze = 0

      if 126 in BanChamps:
        Ban_Jayce += 1
      if 69 in BanChamps:
        Ban_Cassiopeia += 1
      if 24 in BanChamps:
        Ban_Jax += 1
      if 72 in BanChamps:
        Ban_Skarner += 1
      if 68 in BanChamps:
        Ban_Rumble += 1
      if 13 in BanChamps:
        Ban_Ryze += 1
        
	# 팀의 총 데스의 경우, 상대의 총 킬로 가져옴
    else :
      TeamChamp_NDeaths = gameInfo['info']['teams'][j]['objectives']['champion']['kills']

  Analysis_gameID.append(all_gamesID[i])
  tmp_df = pd.DataFrame({'Game':[all_gamesID[i]],
                          'Mode':[gameMode],
                          'GameVersion':[gameVersion],
                          'MapID':[mapID],
                          'User':[userNickname],
                          'Participants': [Participants],
                          'TeamID':[TeamID],
                          'Win':[Win],
                          'StartTime':[UnixTime],
                          'PlayedMin':[PlayedMin],
                          'Position':[Position],
                          'ChampName':[ChampName],

                          'Level': [level],
                          'Exp': [Exp],

                          'TeamBaron_First':[TeamBaron_First],
                          'TeamBaron_NKills':[TeamBaron_NKills],
                          'TeamChamp_First':[TeamChamp_First],
                          'TeamChamp_NKills':[TeamChamp_NKills],
                          'TeamChamp_NDeaths':[TeamChamp_NDeaths],
                          'TeamDragon_First':[TeamDragon_First],
                          'TeamDragon_NKills':[TeamDragon_NKills],
                          'TeamHorde_NKills':[TeamHorde_NKills],
                          'TeamInhibior_First':[TeamInhibior_First],
                          'TeamInhibior_Kills':[TeamInhibior_Kills],
                          'TeamRiftHerald_Kills':[TeamRiftHerald_Kills],
                          'TeamTower_First':[TeamTower_First],
                          'TeamTower_Kills':[TeamTower_Kills],

                          'N_Kill_UnderOwnTurret': [N_Kill_UnderOwnTurret],
                          'N_Kill_UnderEnemyTurret': [N_Kill_UnderEnemyTurret],
                          'N_KDA': [N_KDA],
                          'N_QuickSoloKills': [N_QuickSoloKills],
                          'BountyGold': [N_BountyGold],
                          'N_Ability': [N_Ability],

                          'Ban_Jayce': [Ban_Jayce],
                          'Ban_TwistedFate': [Ban_TwistedFate],
                          'Ban_Cassiopeia': [Ban_Cassiopeia],
                          'Ban_Jax': [Ban_Jax],
                          'Ban_Skarner': [Ban_Skarner],
                          'Ban_Rumble': [Ban_Rumble],

                          'N_assits': [N_assists],
                          'N_deaths': [N_deaths],
                          'N_kills': [N_kills],
                          'N_SoloKills': [N_SoloKills],

                          'N_SkillDodge': [N_SkillDodge],
                          'N_SkillDodge_SmallWindow': [N_SkillDodge_SmallWindow],

                          'N_AssistMePings': [N_AssistMePings],
                          'N_CommandPings': [N_CommandPings],
                          'N_DangerPings': [N_DangerPings],
                          'N_EnemyMissingPings': [N_EnemyMissingPings],
                          'N_GetBackPings': [N_GetBackPings],
                          'N_OnMyWayPings': [N_OnMyWayPings],
                          'N_PushPings': [N_PushPings],

                          'GoldEarned': [GoldEarned],
                          'GoldSpent':  [GoldSpent],

                          'FirstBloodKill': [FirstBloodKill],
                          'FirstBloodAssist': [FirstBloodAssist],
                          'N_ControlWards': [N_ControlWards],

                          'DMGToBuildings': [DMGToBuildings],
                          'DMGToObjectives': [DMGToObjectives],
                          'DMGToTurrets': [DMGToTurrets],

                          'FirstTowerAssist': [FirstTowerAssist],
                          'FirstTowerKill': [FirstTowerKill],
                          'TurretsLost': [TurretsLost],

                          'N_NexusKills': [N_NexusKills],
                          'N_NexusLost': [N_NexusLost],
                          'N_NexusTakeDowns': [N_NexusTakeDowns],

                          'Item_Malignance': [Item_Malignance], 'Item_Liandry':[Item_Liandry],
                          'Item_Rabadon':[Item_Rabadon],
                          'Item_Nashor':[Item_Nashor],
                          'Item_Void':[Item_Void],
                          'Item_Cryptbloom':[Item_Cryptbloom],
                          'Items':[items],

                          'LongestTimeSpentLiving': [LongestTimeSpentLiving],
                          'TotalTimeSpentDead': [TotalTimeSpentDead],
                          'PrimaryPerk': [PrimaryPerk],
                          'TotalDMG': [TotalDMG],
                          'TotalTakenDMG': [TotalTakenDMG],
                          'N_Minions': [N_Minions],
                          'Score_Vision': [Score_Vision],
                          'WardsBought': [WardsBought],
                          'WardsPlaced': [WardsPlaced],
                          'WardsKilled': [WardsKilled],
                          'DetectorWardsPlaced': [DetectorWardsPlaced]
                          })

  Analysis_df = pd.concat([Analysis_df, tmp_df])

 

 

반응형

'Python > API' 카테고리의 다른 글

[Riot API] 0. API Key 발급과 기본 데이터 수집  (0) 2024.06.20