puuid, matchid sql DB์ ์ ์ฅํ๊ธฐ
ํ๋์ ๊ธ์ด ๋ธํ๋ ์ด์ ๋ ์ถ์ ์ฐํด๋ด๋ด DB๋ฅผ ๊ตฌ์ถํ๊ธฐ ๋๋ฌธ์ ๋๋ค.
riot api rate limit ๋๋ฌธ์ 1์๊ฐ์ 2์ฒ๊ฐ ๋ฐ์ดํฐ ์ถ์ถ์ด ์ต๋์ ๋๋ค...
import mysql.connector
# MySQL ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฐ๊ฒฐ
connection = mysql.connector.connect(
host="localhost", # MySQL ์๋ฒ ์ฃผ์
user="root", # MySQL ์ฌ์ฉ์๋ช
password="0224", # MySQL ๋น๋ฐ๋ฒํธ
database="riot_game_database" # ์ฌ์ฉํ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ด๋ฆ
)
# ์ปค์ ์์ฑ
cursor = connection.cursor()
# puuid์ match_id ๋ฐ์ดํฐ๋ฅผ ํ
์ด๋ธ์ ์ฝ์
ํ๋ ํจ์
def insert_match_id(puuid, match_id):
sql = """
INSERT INTO summoner_puuid (puuid, match_id)
VALUES (%s, %s)
"""
cursor.execute(sql, (puuid, match_id))
# puuid์ ๊ฐ๊ฐ์ match_id๋ฅผ ํ
์ด๋ธ์ ์ฝ์
for entry in summoner_matchID_list:
puuid = entry['puuid']
match_ids = entry['match_ids']
for match_id in match_ids:
insert_match_id(puuid, match_id)
# ๋ณ๊ฒฝ์ฌํญ ์ปค๋ฐ
connection.commit()
# ์ปค์์ ์ฐ๊ฒฐ ์ข
๋ฃ
cursor.close()
connection.close()
์ผ๋จ puuid์ match_id๋ฅผ DB์ ๋ด์์ต๋๋ค.
SQL ์๋ฒ ์ฐ๊ฒฐ ๋ฐ ๋ฐ์ดํฐ ๋ถํ
ex1_match_ids=match_ids[:2000]
ex2_match_ids=match_ids[2001:4001]
ex3_match_ids=match_ids[4002:6002]
ex4_match_ids=match_ids[6003:8003]
ex5_match_ids=match_ids[8004:10004]
ex6_match_ids=match_ids[10005:10250]
import mysql.connector
# MySQL ์๋ฒ์ ์ฐ๊ฒฐ
connection = mysql.connector.connect(
host="localhost", # MySQL ์๋ฒ ํธ์คํธ ์ด๋ฆ (๋ณดํต ๋ก์ปฌ์ผ ๊ฒฝ์ฐ localhost)
user="root", # MySQL ์ฌ์ฉ์ ์ด๋ฆ
password="0224", # MySQL ์ฌ์ฉ์ ๋น๋ฐ๋ฒํธ
database="riot_game_database" # ์ฌ์ฉํ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ด๋ฆ
)
# ์ฐ๊ฒฐ์ด ์ฑ๊ณตํ๋์ง ํ์ธ
if connection.is_connected():
print("MySQL ์ฐ๊ฒฐ ์ฑ๊ณต")
else:
print("MySQL ์ฐ๊ฒฐ ์คํจ")
ํ๋ฒ์ 10250๊ฐ(250๋ช x 10ํ์๋ฐ์ดํฐ) ๋ฅผ ๊ฐ์ ธ์ค๋ฉด ์ค๋ฅ๊ฐ ๋ ๊ฒ ๊ฐ์์ 2000๊ฐ์ฉ ๋์ด์ ๊ฐ์ ธ์์ต๋๋ค.
MATCHID๋ฅผ ํธ์ถํ์ฌ ์ํ๋ ์ ๋ณด๋ง SQL DB์ ์ ์ฅํ๊ธฐ
import aiohttp
import asyncio
from asyncio_throttle import Throttler
# ๋น๋๊ธฐ์ ์ผ๋ก match ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๋ ํจ์
async def fetch_match_data(session, match_id, api_key, throttler):
url = f"https://asia.api.riotgames.com/lol/match/v5/matches/{match_id}"
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36 Edg/128.0.0.0",
"Accept-Language": "ko,en;q=0.9,en-US;q=0.8",
"Accept-Charset": "application/x-www-form-urlencoded; charset=UTF-8",
"Origin": "https://developer.riotgames.com",
"X-Riot-Token": api_key
}
async with throttler: # ์์ฒญ ์๋ ์ ํ
async with session.get(url, headers=headers) as response:
if response.status == 429: # Rate limit ์ฒ๋ฆฌ
retry_after = int(response.headers.get('Retry-After', 60)) # Retry-After ํค๋ ํ์ธ
print(f"Rate limit exceeded for match {match_id}. Sleeping for {retry_after} seconds.")
await asyncio.sleep(retry_after) # ๋น๋๊ธฐ ๋๊ธฐ
return await fetch_match_data(session, match_id, api_key, throttler) # ๋ค์ ์๋
elif response.status == 200:
match_data = await response.json() # JSON ๋ฐ์ดํฐ ๋ฐํ
queue_id = match_data.get('info', {}).get('queueId', None)
if queue_id == 420: # Solo Rank ๋ชจ๋ (Queue ID 420)๋ง ๊ฐ์ ธ์ด
return match_data
else:
print(f"Skipping match {match_id} because queueId is not 420")
return None
else:
print(f"Error: {response.status} for match ID {match_id}")
return None
async def fetch_all_matches(ex5_match_ids, api_key):
throttler = Throttler(rate_limit=20, period=1) # ์ด๋น 20๊ฐ์ ์์ฒญ์ผ๋ก ์ ํ
async with aiohttp.ClientSession() as session:
tasks = [fetch_match_data(session, match_id, api_key, throttler) for match_id in ex5_match_ids]
responses = await asyncio.gather(*tasks)
for response in responses:
if response is None:
print("Failed to fetch data for a match.")
return [response for response in responses if response is not None]
# MYSQL ์ฐ๊ฒฐ ์ค์
def create_db_connection():
connection = mysql.connector.connect(
host="localhost", # MySQL ์๋ฒ ํธ์คํธ ์ด๋ฆ (๋ณดํต ๋ก์ปฌ์ผ ๊ฒฝ์ฐ localhost)
user="root", # MySQL ์ฌ์ฉ์ ์ด๋ฆ
password="0224", # MySQL ์ฌ์ฉ์ ๋น๋ฐ๋ฒํธ
database="riot_game_database" # ์ฌ์ฉํ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ด๋ฆ
)
return connection
# MYSQL ์ ๋งค์น ๋ฐ์ดํฐ๋ฅผ ์ฝ์
def insert_match_data(connection,match_data):
cursor=connection.cursor()
for match in match_data:
match_id = match.get('metadata', {}).get('matchId', 'Unknown Match ID')
inser_query = """
INSERT INTO matches5 (match_id, summoner_name, puuid, kills, deaths, gold_earned, wards_placed, wards_bought, css, assists, kda, teamPosition)
VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)
"""
for participant in match.get('info', {}).get('participants', []):
data = ( match.get('metadata', {}).get('matchId', 'Unknown Match ID'),
participant.get('summonerName'),
participant.get('puuid'), # puuid ์ถ๊ฐ
participant.get('kills'),
participant.get('deaths'),
participant.get('goldEarned', 0),
participant.get('wardPlaced', 0),
participant.get('visionWardsBoughtInGame', 0),
(participant.get('totalMinionsKilled', 0) + participant.get('neutralMinionsKilled', 0)) / (match.get('info', {}).get('gameDuration', 1) / 60),
participant.get('assists'),
participant.get('challenges', {}).get('kda'),
participant.get('teamPosition') # teamPosition ์ถ๊ฐ
)
try:
cursor.execute(inser_query, data)
except mysql.connector.Error as err:
print(f"Error: {err}")
connection.commit()
cursor.close()
# ๋น๋๊ธฐ ๋ฉ์ธ ํจ์
async def main():
api_key = "MY_API" # Riot Games API ํค
# ๋ชจ๋ match_ids์ ๋ํด ๊ฒ์ ์ ๋ณด ๊ฐ์ ธ์ค๊ธฐ
match_data_list = await fetch_all_matches(ex5_match_ids, api_key)
# mysql ์ฐ๊ฒฐ ๋ฐ ๋ฐ์ดํฐ ์ฝ์
connection=create_db_connection()
insert_match_data(connection,match_data_list)
connection.close()
# asyncio ์คํ
await main()
๋ฌธ์ ๊ฐ ์์ต๋๋ค. ์ฝ๋๊ฐ ์ ์คํ๋๋ค๊ฐ ์ค๋ฅ๊ฐ ๋ฌ์ง ๋ญก๋๊น
๋ถ๋ช ex1~4๊น์ง ์ ๋๋๋ฐ ex5์์ ์ค๋ฅ๊ฐ ๋ฌ์ต๋๋ค.
css๋ฅผ ๊ณ์ฐํ๋ ์์ด ์๋์ ๊ฐ์๋ฐ ๋ถ๋ชจ์ 0์ด ๋ค์ด๊ฐ๋ ๊ฐ์ด ์๋ ๊ฒ ๊ฐ์ต๋๋ค..
(participant.get('totalMinionsKilled', 0) + participant.get('neutralMinionsKilled', 0)) / (match.get('info', {}).get('gameDuration', 1) / 60)
๊ฒ์์๊ฐ์ด 0์ธ ๊ฒฝ์ฐ๊ฐ ์๋ ๊ฒ ๊ฐ์ต๋๋ค.
API์ค๋ฅ์ธ์ง ๊บผ๋ฒ๋ฆฐ ๊ฑด์ง๋ ๋ชจ๋ฅด๊ฒ ์ง๋ง ํด๋น ์ค๋ฅ์ผ ๊ฒฝ์ฐ๋ ๊ณ์ฐํด์ฃผ๋ ์ฝ๋๋ก ๋ค์์์ ํฉ๋๋ค.
import aiohttp
import asyncio
import mysql.connector
from asyncio_throttle import Throttler
# ๋น๋๊ธฐ์ ์ผ๋ก match ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๋ ํจ์
async def fetch_match_data(session, match_id, api_key, throttler):
url = f"https://asia.api.riotgames.com/lol/match/v5/matches/{match_id}"
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36 Edg/128.0.0.0",
"Accept-Language": "ko,en;q=0.9,en-US;q=0.8",
"Accept-Charset": "application/x-www-form-urlencoded; charset=UTF-8",
"Origin": "https://developer.riotgames.com",
"X-Riot-Token": api_key
}
async with throttler: # ์์ฒญ ์๋ ์ ํ
async with session.get(url, headers=headers) as response:
if response.status == 429: # Rate limit ์ฒ๋ฆฌ
retry_after = int(response.headers.get('Retry-After', 60)) # Retry-After ํค๋ ํ์ธ
print(f"Rate limit exceeded for match {match_id}. Sleeping for {retry_after} seconds.")
await asyncio.sleep(retry_after) # ๋น๋๊ธฐ ๋๊ธฐ
return await fetch_match_data(session, match_id, api_key, throttler) # ๋ค์ ์๋
elif response.status == 200:
match_data = await response.json() # JSON ๋ฐ์ดํฐ ๋ฐํ
queue_id = match_data.get('info', {}).get('queueId', None)
if queue_id == 420: # Solo Rank ๋ชจ๋ (Queue ID 420)๋ง ๊ฐ์ ธ์ด
return match_data
else:
print(f"Skipping match {match_id} because queueId is not 420")
return None
else:
print(f"Error: {response.status} for match ID {match_id}")
return None
async def fetch_all_matches(ex5_match_ids, api_key):
throttler = Throttler(rate_limit=20, period=1) # ์ด๋น 20๊ฐ์ ์์ฒญ์ผ๋ก ์ ํ
async with aiohttp.ClientSession() as session:
tasks = [fetch_match_data(session, match_id, api_key, throttler) for match_id in ex5_match_ids]
responses = await asyncio.gather(*tasks)
return [response for response in responses if response is not None]
# MYSQL ์ฐ๊ฒฐ ์ค์
def create_db_connection():
connection = mysql.connector.connect(
host="localhost", # MySQL ์๋ฒ ํธ์คํธ ์ด๋ฆ
user="root", # MySQL ์ฌ์ฉ์ ์ด๋ฆ
password="0224", # MySQL ์ฌ์ฉ์ ๋น๋ฐ๋ฒํธ
database="riot_game_database" # ์ฌ์ฉํ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ด๋ฆ
)
return connection
# MYSQL์ ๋งค์น ๋ฐ์ดํฐ๋ฅผ ์ฝ์
def insert_match_data(connection, match_data):
cursor = connection.cursor()
for match in match_data:
match_id = match.get('metadata', {}).get('matchId', 'Unknown Match ID')
inser_query = """
INSERT INTO matches5 (match_id, summoner_name, puuid, kills, deaths, gold_earned, wards_placed, wards_bought, css, assists, kda, teamPosition)
VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)
"""
for participant in match.get('info', {}).get('participants', []):
total_minions_killed = participant.get('totalMinionsKilled', 0)
neutral_minions_killed = participant.get('neutralMinionsKilled', 0)
game_duration = match.get('info', {}).get('gameDuration', 1) / 60 # ๋ถ ๋จ์๋ก ๋ณํ
# ๊ฒ์ ์๊ฐ์ด 0์ผ ๊ฒฝ์ฐ ์ฒ๋ฆฌ
css = (total_minions_killed + neutral_minions_killed) / game_duration if game_duration > 0 else 0
data = (
match_id,
participant.get('summonerName'),
participant.get('puuid'),
participant.get('kills'),
participant.get('deaths'),
participant.get('goldEarned', 0),
participant.get('wardsPlaced', 0),
participant.get('visionWardsBoughtInGame', 0),
css,
participant.get('assists'),
participant.get('challenges', {}).get('kda'),
participant.get('teamPosition')
)
try:
cursor.execute(inser_query, data)
except mysql.connector.Error as err:
print(f"Error: {err}")
connection.commit()
cursor.close()
# ๋น๋๊ธฐ ๋ฉ์ธ ํจ์
async def main():
api_key = "MY_API" # Riot Games API ํค
match_data_list = await fetch_all_matches(ex5_match_ids, api_key)
# MySQL ์ฐ๊ฒฐ ๋ฐ ๋ฐ์ดํฐ ์ฝ์
connection = create_db_connection()
insert_match_data(connection, match_data_list)
connection.close()
# asyncio ์คํ
await main()
์ด์ ๊ฒ์์๊ฐ์ด 0์ธ ๊ฒฝ์ฐ๋ ์ ๋๋ก ํธ์ถํ ์ ์์ต๋๋ค.
DB์์ ์๋ก๋ญํฌ์ ํด๋นํ๋ ๊ฒ๋ง ๋ค์ ๊ฐ์ ธ์์ 9์ฒ๊ฐ๊ฐ ์กฐ๊ธ ๋๋ ๋ฐ์ดํฐ๋ง ๋จ๊ฒ ๋์์ต๋๋ค.
matchid๋ ์๋ ๋ ๋ชจ๋๋ ํฌํจ๋์ด ์๊ธฐ์ ๊ทธ ๋ถ๋ถ์ ์ ์ธํ์์ต๋๋ค.
์ด์ ์ด DB๋ฅผ ๊ฐ์ง๊ณ ์ ์ ๋ค์ ํ๊ท ์ ํ๋ธ๋ก๋ก ๊ตฌํํ ์์ ์ ๋๋ค.