[OPGG] 라이엇 API 사용하기

Updated:

1. 내전 게임 불러오기

import pandas as pd
import numpy as np
import requests
import matplotlib as plt

# Riot Developer Portal에서 받은 API KEY입니다.
# 해당 값을 포함한 모든 종류의 KEY는 코드에 직접적으로 노출되지 않도록 하는 것이 좋습니다.
api_key = 'RGAPI-0c612bd4-12a0-4358-8d6b-9ea0cd92b1cf'

# 방금 진행한 내전의 gameId값입니다. 클라이언트 대전기록에서 확인할 수 있습니다.
gameid = 5382324388
requesturl = "https://kr.api.riotgames.com/lol/match/v4/matches/"+str(gameid)+"?api_key="+api_key
r = requests.get(requesturl)
  • 라이엇 개발자 홈페이지에서 API 탭에 가면 여러 자료를 불러올 수 있다.

  • 이번엔 그 중에서 강의 중 내전한 자료를 불러올 것이다.

  • gameid는 롤 대전기록 검색시 URL에서 확인 가능하다.

  • API KEY는 24시간 정도 유지되며 그 이후 사용시 재발급하여 사용하면 된다.

# 불러온 데이터 확인
# teamid 100: blue, 200: red
r.json().keys()
dict_keys(['gameId', 'platformId', 'gameCreation', 'gameDuration', 'queueId', 'mapId', 'seasonId', 'gameVersion', 'gameMode', 'gameType', 'teams', 'participants', 'participantIdentities'])
  • 불러온 데이터는 json 형식의 파일로 이루어져 있다.

  • 각 key별로 어떤 자료가 있는지는 홈페이지에 자세한 설명이 있다.

# 불러온 데이터 중 소환사1의 데이터 확인
# r.json()['participants'][0]
  • participants에는 플레이한 소환사의 정보가 담겨있다.
# DataFrame으로 변환해서 확인
pd.DataFrame(r.json()['participants'])
participantId teamId championId spell1Id spell2Id stats timeline
0 1 100 222 7 4 {'participantId': 1, 'win': False, 'item0': 10... {'participantId': 1, 'creepsPerMinDeltas': {'1...
1 2 100 234 4 11 {'participantId': 2, 'win': False, 'item0': 31... {'participantId': 2, 'creepsPerMinDeltas': {'1...
2 3 100 143 4 14 {'participantId': 3, 'win': False, 'item0': 66... {'participantId': 3, 'creepsPerMinDeltas': {'1...
3 4 100 34 12 4 {'participantId': 4, 'win': False, 'item0': 30... {'participantId': 4, 'creepsPerMinDeltas': {'1...
4 5 100 58 4 14 {'participantId': 5, 'win': False, 'item0': 66... {'participantId': 5, 'creepsPerMinDeltas': {'1...
5 6 200 48 12 4 {'participantId': 6, 'win': True, 'item0': 304... {'participantId': 6, 'creepsPerMinDeltas': {'1...
6 7 200 84 14 4 {'participantId': 7, 'win': True, 'item0': 105... {'participantId': 7, 'creepsPerMinDeltas': {'1...
7 8 200 43 14 4 {'participantId': 8, 'win': True, 'item0': 385... {'participantId': 8, 'creepsPerMinDeltas': {'1...
8 9 200 203 11 4 {'participantId': 9, 'win': True, 'item0': 313... {'participantId': 9, 'creepsPerMinDeltas': {'1...
9 10 200 498 7 4 {'participantId': 10, 'win': True, 'item0': 10... {'participantId': 10, 'creepsPerMinDeltas': {'...
  • 이를 데이터프레임으로 바꿔보면 앞서 지정한 특정 게임의 플레이어 10명에 대한 정보가 담겨있다.

  • 다만 stats와 timeline 등은 nested되어 있다.

# nested된 부분 unnest해서 DataFrame으로 변환
df = pd.json_normalize(r.json()['participants'])
df.head()
participantId teamId championId spell1Id spell2Id stats.participantId stats.win stats.item0 stats.item1 stats.item2 ... timeline.csDiffPerMinDeltas.10-20 timeline.csDiffPerMinDeltas.0-10 timeline.xpDiffPerMinDeltas.10-20 timeline.xpDiffPerMinDeltas.0-10 timeline.damageTakenPerMinDeltas.10-20 timeline.damageTakenPerMinDeltas.0-10 timeline.damageTakenDiffPerMinDeltas.10-20 timeline.damageTakenDiffPerMinDeltas.0-10 timeline.role timeline.lane
0 1 100 222 7 4 1 False 1055 6671 3094 ... -1.1 -0.65 36.35 -24.55 638.7 252.8 64.95 -4.7 DUO_CARRY BOTTOM
1 2 100 234 4 11 2 False 3153 2031 3047 ... -0.9 0.20 -77.30 -97.40 1354.3 892.3 294.40 206.7 NONE JUNGLE
2 3 100 143 4 14 3 False 6653 2421 3853 ... -1.1 -0.65 36.35 -24.55 482.4 224.7 64.95 -4.7 DUO_SUPPORT BOTTOM
3 4 100 34 12 4 4 False 3040 6653 0 ... 0.6 0.30 36.60 -52.30 546.4 127.0 43.10 -189.6 SOLO MIDDLE
4 5 100 58 4 14 5 False 6630 2031 3075 ... -1.9 -1.00 -99.20 4.30 1157.8 683.7 18.90 103.7 SOLO TOP

5 rows × 126 columns

  • pd.json_normalize()를 사용하면 다음과 같이 원하는 형태로 생성 가능하다.
# 확인할 변수
COLUMNS = ["participantId", "teamId", "championId", "spell1Id", "spell2Id", "stats.win",
           "stats.item0","stats.item1","stats.item2","stats.item3","stats.item4","stats.item5","stats.item6",
           "stats.kills","stats.deaths","stats.assists","stats.totalDamageDealt","stats.totalDamageTaken",
           "stats.goldEarned"]
# 확인할 변수만 가져와서 새로운 DataFrame에 저장
df2 = df[COLUMNS]
# Column 이름에 불필요한 'stats.'가 붙은 걸 삭제
df2.columns = df2.columns.str.replace('stats.', '', regex = True)
# 최종 추출 형태 확인
df2
participantId teamId championId spell1Id spell2Id win item0 item1 item2 item3 item4 item5 item6 kills deaths assists totalDamageDealt totalDamageTaken goldEarned
0 1 100 222 7 4 False 1055 6671 3094 3006 1038 1037 3363 7 6 8 85575 16660 9877
1 2 100 234 4 11 False 3153 2031 3047 0 0 6632 3364 6 9 10 84491 32960 9053
2 3 100 143 4 14 False 6653 2421 3853 3020 3191 1028 3364 3 6 11 37787 12358 7565
3 4 100 34 12 4 False 3040 6653 0 0 3020 0 3364 4 5 4 101048 14466 8237
4 5 100 58 4 14 False 6630 2031 3075 3047 1054 0 3364 5 7 2 70397 29663 8345
5 6 200 48 12 4 True 3047 1054 6632 3051 3742 3076 3340 3 5 11 107619 27460 10940
6 7 200 84 14 4 True 1054 3020 3157 1052 4633 0 3340 2 2 5 64034 13449 8417
7 8 200 43 14 4 True 3853 2065 2055 3011 3158 0 3364 0 4 18 22255 9783 7729
8 9 200 203 11 4 True 3139 3026 3006 6672 6676 3094 3364 23 7 7 200929 24914 18384
9 10 200 498 7 4 True 1055 6671 3508 1038 0 3006 3363 5 7 7 116952 13582 10475
  • 각 플레이어의 팀, 선택한 챔피언, 스펠, 승리 여부 등 일부 정보만 불러왔다.
# KDA = (K + A) / D
# GPM = goldEarned / (gameDuration_In_Munite)
# DPM = damageDealt / (gameDuration_In_Munite)
# DTPM = damageTaken / (gameDuration_In_Munite)
df3 = df2.assign(KDA=lambda x: (x['kills']+x['assists'])/x['deaths'])
df3['GPM'] = df3['goldEarned'] / r.json()['gameDuration'] * 60 # 분 단위
df3['DPM'] = df3['totalDamageDealt'] / r.json()['gameDuration'] * 60
df3['DTPM'] = df3['totalDamageTaken'] / r.json()['gameDuration'] * 60
  • KDA, GPM 등 개인 지표를 추가하였다.

  • KDA의 경우 Death가 0인 경우를 고려해서 짜도 될 것이다.

df3
participantId teamId championId spell1Id spell2Id win item0 item1 item2 item3 ... kills deaths assists totalDamageDealt totalDamageTaken goldEarned KDA GPM DPM DTPM
0 1 100 222 7 4 False 1055 6671 3094 3006 ... 7 6 8 85575 16660 9877 2.500000 368.086957 3189.130435 620.869565
1 2 100 234 4 11 False 3153 2031 3047 0 ... 6 9 10 84491 32960 9053 1.777778 337.378882 3148.732919 1228.322981
2 3 100 143 4 14 False 6653 2421 3853 3020 ... 3 6 11 37787 12358 7565 2.333333 281.925466 1408.211180 460.546584
3 4 100 34 12 4 False 3040 6653 0 0 ... 4 5 4 101048 14466 8237 1.600000 306.968944 3765.763975 539.105590
4 5 100 58 4 14 False 6630 2031 3075 3047 ... 5 7 2 70397 29663 8345 1.000000 310.993789 2623.490683 1105.453416
5 6 200 48 12 4 True 3047 1054 6632 3051 ... 3 5 11 107619 27460 10940 2.800000 407.701863 4010.645963 1023.354037
6 7 200 84 14 4 True 1054 3020 3157 1052 ... 2 2 5 64034 13449 8417 3.500000 313.677019 2386.360248 501.204969
7 8 200 43 14 4 True 3853 2065 2055 3011 ... 0 4 18 22255 9783 7729 4.500000 288.037267 829.378882 364.583851
8 9 200 203 11 4 True 3139 3026 3006 6672 ... 23 7 7 200929 24914 18384 4.285714 685.118012 7488.037267 928.472050
9 10 200 498 7 4 True 1055 6671 3508 1038 ... 5 7 7 116952 13582 10475 1.714286 390.372671 4358.459627 506.161491

10 rows × 23 columns

# 숫자로 된 각종 Key값에 대한 Value 가져오기
champion_constant = requests.get("http://ddragon.leagueoflegends.com/cdn/11.15.1/data/ko_KR/champion.json")
spell_constant = requests.get("http://ddragon.leagueoflegends.com/cdn/11.15.1/data/ko_KR/summoner.json")
item_constant = requests.get("http://ddragon.leagueoflegends.com/cdn/11.15.1/data/ko_KR/item.json")
  • 챔피언, 스펠, 아이템에 대한 json 파일을 불러왔다.

  • 이 역시 홈페이지에서 해당 URL을 확인 가능하다.

  • 수업 당시 기준 11.15.1 버전 URL이나 업데이트 된다면 이를 바꿔주면 된다.

# champion_constant.json()
# Json 파일을 DataFrame으로 변환
champion_df = pd.DataFrame(champion_constant.json()['data']).T[['key','name']]
spell_df = pd.DataFrame(spell_constant.json()['data']).T[['key','name']]
item_df = pd.DataFrame(item_constant.json()['data']).T['name'].rename_axis("key").reset_index()

# 변수형 문자 -> 숫자
champion_df['key'] = pd.to_numeric(champion_df['key'])
spell_df['key'] = pd.to_numeric(spell_df['key'])
item_df['key'] = pd.to_numeric(item_df['key'])
  • 이번에도 데이터 프레임 형태로 바꿔주되 각 파일의 컬럼이 매우 많아 일부만 사용한다.
# 매칭되는 곳으로 내용 추가하여 새로운 DataFrame으로 저장
df4 = pd.merge(df3,champion_df,how = 'left', left_on = 'championId', right_on = 'key')
# DataFrame 확인
df4
participantId teamId championId spell1Id spell2Id win item0 item1 item2 item3 ... assists totalDamageDealt totalDamageTaken goldEarned KDA GPM DPM DTPM key name
0 1 100 222 7 4 False 1055 6671 3094 3006 ... 8 85575 16660 9877 2.500000 368.086957 3189.130435 620.869565 222 징크스
1 2 100 234 4 11 False 3153 2031 3047 0 ... 10 84491 32960 9053 1.777778 337.378882 3148.732919 1228.322981 234 비에고
2 3 100 143 4 14 False 6653 2421 3853 3020 ... 11 37787 12358 7565 2.333333 281.925466 1408.211180 460.546584 143 자이라
3 4 100 34 12 4 False 3040 6653 0 0 ... 4 101048 14466 8237 1.600000 306.968944 3765.763975 539.105590 34 애니비아
4 5 100 58 4 14 False 6630 2031 3075 3047 ... 2 70397 29663 8345 1.000000 310.993789 2623.490683 1105.453416 58 레넥톤
5 6 200 48 12 4 True 3047 1054 6632 3051 ... 11 107619 27460 10940 2.800000 407.701863 4010.645963 1023.354037 48 트런들
6 7 200 84 14 4 True 1054 3020 3157 1052 ... 5 64034 13449 8417 3.500000 313.677019 2386.360248 501.204969 84 아칼리
7 8 200 43 14 4 True 3853 2065 2055 3011 ... 18 22255 9783 7729 4.500000 288.037267 829.378882 364.583851 43 카르마
8 9 200 203 11 4 True 3139 3026 3006 6672 ... 7 200929 24914 18384 4.285714 685.118012 7488.037267 928.472050 203 킨드레드
9 10 200 498 7 4 True 1055 6671 3508 1038 ... 7 116952 13582 10475 1.714286 390.372671 4358.459627 506.161491 498 자야

10 rows × 25 columns

  • 챔피언 id를 기준으로 각 id가 어떤 챔피언인지 알 수 있게 merge한 결과이다.
# 중복되는 값 삭제
df4 = df4.rename(columns={'name': 'Champion'}).drop(['championId','key'],axis = 1)
df4 = pd.merge(df4,spell_df,how = 'left', left_on = 'spell1Id', right_on = 'key')
df4 = df4.rename(columns={'name': 'D'}).drop(['spell1Id','key'],axis = 1)
df4 = pd.merge(df4,spell_df,how = 'left', left_on = 'spell2Id', right_on = 'key')
df4 = df4.rename(columns={'name': 'F'}).drop(['spell2Id','key'],axis = 1)
df4 = pd.merge(df4,item_df,how = 'left', left_on = 'item0', right_on = 'key')
df4 = df4.rename(columns={'name': 'Item1'}).drop(['item0','key'],axis = 1)
df4 = pd.merge(df4,item_df,how = 'left', left_on = 'item1', right_on = 'key')
df4 = df4.rename(columns={'name': 'Item2'}).drop(['item1','key'],axis = 1)
df4 = pd.merge(df4,item_df,how = 'left', left_on = 'item2', right_on = 'key')
df4 = df4.rename(columns={'name': 'Item3'}).drop(['item2','key'],axis = 1)
df4 = pd.merge(df4,item_df,how = 'left', left_on = 'item3', right_on = 'key')
df4 = df4.rename(columns={'name': 'Item4'}).drop(['item3','key'],axis = 1)
df4 = pd.merge(df4,item_df,how = 'left', left_on = 'item4', right_on = 'key')
df4 = df4.rename(columns={'name': 'Item5'}).drop(['item4','key'],axis = 1)
df4 = pd.merge(df4,item_df,how = 'left', left_on = 'item5', right_on = 'key')
df4 = df4.rename(columns={'name': 'Item6'}).drop(['item5','key'],axis = 1)
df4 = pd.merge(df4,item_df,how = 'left', left_on = 'item6', right_on = 'key')
df4 = df4.rename(columns={'name': 'Trinket'}).drop(['item6','key'],axis = 1)
  • 같은 방법으로 스펠과 아이템의 이름을 확인하기 위해 merge한다.
# 확인할 변수
COLUMNS_NEW = ["participantId", "teamId","win", "Champion", "D", "F", "KDA",
           "kills","deaths","assists","Item1","Item2","Item3","Item4","Item5","Item6","Trinket","GPM","DPM","DTPM"]
df5 = df4[COLUMNS_NEW]
df5
participantId teamId win Champion D F KDA kills deaths assists Item1 Item2 Item3 Item4 Item5 Item6 Trinket GPM DPM DTPM
0 1 100 False 징크스 회복 점멸 2.500000 7 6 8 도란의 검 돌풍 고속 연사포 광전사의 군화 B.F. 대검 곡괭이 망원형 개조 368.086957 3189.130435 620.869565
1 2 100 False 비에고 점멸 강타 1.777778 6 9 10 몰락한 왕의 검 충전형 물약 판금 장화 NaN NaN 신성한 파괴자 예언자의 렌즈 337.378882 3148.732919 1228.322981
2 3 100 False 자이라 점멸 점화 2.333333 3 6 11 리안드리의 고뇌 망가진 초시계 얼음 정수의 파편 마법사의 신발 추적자의 팔목 보호대 루비 수정 예언자의 렌즈 281.925466 1408.211180 460.546584
3 4 100 False 애니비아 순간이동 점멸 1.600000 4 5 4 대천사의 포옹 리안드리의 고뇌 NaN NaN 마법사의 신발 NaN 예언자의 렌즈 306.968944 3765.763975 539.105590
4 5 100 False 레넥톤 점멸 점화 1.000000 5 7 2 선혈포식자 충전형 물약 가시 갑옷 판금 장화 도란의 방패 NaN 예언자의 렌즈 310.993789 2623.490683 1105.453416
5 6 200 True 트런들 순간이동 점멸 2.800000 3 5 11 판금 장화 도란의 방패 신성한 파괴자 온기가 필요한 자의 도끼 망자의 갑옷 덤불 조끼 투명 와드 407.701863 4010.645963 1023.354037
6 7 200 True 아칼리 점화 점멸 3.500000 2 2 5 도란의 방패 마법사의 신발 존야의 모래시계 증폭의 고서 균열 생성기 NaN 투명 와드 313.677019 2386.360248 501.204969
7 8 200 True 카르마 점화 점멸 4.500000 0 4 18 얼음 정수의 파편 슈렐리아의 군가 제어 와드 화학공학 부패기 명석함의 아이오니아 장화 NaN 예언자의 렌즈 288.037267 829.378882 364.583851
8 9 200 True 킨드레드 강타 점멸 4.285714 23 7 7 헤르메스의 시미터 수호 천사 광전사의 군화 크라켄 학살자 징수의 총 고속 연사포 예언자의 렌즈 685.118012 7488.037267 928.472050
9 10 200 True 자야 회복 점멸 1.714286 5 7 7 도란의 검 돌풍 정수 약탈자 B.F. 대검 NaN 광전사의 군화 망원형 개조 390.372671 4358.459627 506.161491
  • 최종적으로 이 게임의 정보에 대해 위와 같이 확인 가능하다.

  • 이 게임은 red팀이 승리하였고 킨드레드가 하드캐리한 것이 KDA, DPM 등을 통해 보인다.

Leave a comment