본문 바로가기

게임/리그오브레전드 - Riot API

리그오브레전드 게임 데이터 수집기 만들기 [4-3화: 데이터 수집기_관리용 함수들]

 #collect() 인자: 소환사명, 결과: new_before.json 파일 생성

-등장한 챔피언이 무엇인지, 어떤 챔피언이 어떤 팀이었는지를 알아내고

-각 챔피언들이 어떤 포지션이었는지(탑인지 미드인지 원딜인지 등) 알아냅니다.

*사실 api에서도 포지션에 대한 정보를 주지만 아주 부정확합니다ㅠㅠ

 

-마지막으로 자체적으로 만든 포지션과 팀에 대한 정보가 논리적으로 맞는지 검사합니다.

(각 팀의 인원이 5인이 맞는지, 각 포지션별로 인원 수가 맞는지, 혹시 원딜로 분류된 게 두명은 아닌지 등등)

 

-검사가 끝나고 정상이면 최종 데이터 저장용 파일(new_before.json)에 반영합니다.

#수집기의 최종 자료인 new_before.json을 만드는 부분입니다.
def collect(nick):
	print(nick,'의 정보 분석 시작')
	#닉 -> 어카운트
	account=summonerName_to_accountId(nick)
	#어카운트 -> 게임아디
	gameid = from_accountId_get_gameid(account)

	##5대5 게임인 롤에는 [top, mid, jungle, bottom, support] 5개의 포지션이 있습니다. 
	#이 아래로는 게임아이디를 -> 각 팀별, 포지션별 챔피언이 무엇인지 구분하는 부분입니다.
	global position
	url = 'https://kr.api.riotgames.com/lol/match/v4/timelines/by-match/'+gameid+'?api_key='+api_key
	position = req_api(url)
	global ffdata
	uurl = 'https://kr.api.riotgames.com/lol/match/v4/matches/'+gameid+'?api_key='+api_key
	ffdata = req_api(uurl)

	#api에서 시스템적 요소인 팀은 잘 구분해줍니다. 포지션은 api의 정확도가 떨어집니다. 그래서 포지션을 알아낼 부분은 따로 만들어야했습니다.
	#아래 세개의 행은 시간대별 위치좌표를 이용하여 어느 캐릭터가 어떤포지션이었는지를 알아내는 부분입니다.
	top=get_top_full(gameid)
	midjg=get_mid_full(gameid)
	bot=get_bottom_full(gameid)
	

	#이 아래로는 최종적으로 100팀과 200팀의 top,mid,jg,sup,bot과 승팀, 패팀을 구분하여 최종 데이터를 구성하는 부분입니다.
	#자료가 오류자료가 아닌지 마지막으로 확인하는 부분이기도 합니다
	#포지션별로 100팀과 200팀의 인원수가 맞는지 점검하고 맞다면 각 팀 딕셔너리의 포지션 key에 챔피언명을 기입합니다. 
	thisgame = {}
	team_100={}
	team_200={}
	if len(top)==3:
		if top[0][0]==100 and top[1][0] ==200:
			team_100['top']=top[0][1]
			team_200['top']=top[1][1]
		elif top[0][0]==200 and top[1][0] ==100:
			team_200['top']=top[0][1]
			team_100['top']=top[1][1]
		else:
			return -1
	else:
		return 0



	if len(midjg)==5:
		if midjg[0][0]==100 and midjg[1][0]==100 and midjg[2][0]==200 and midjg[3][0]==200:
			team_100['jungle']=midjg[1][1]
			team_100['mid'] = midjg[0][1]
			team_200['jungle'] = midjg[3][1]
			team_200['mid']=midjg[2][1]
		elif midjg[0][0]==200 and midjg[1][0]==200 and midjg[2][0]==100 and midjg[3][0]==100:
			team_200['jungle']=midjg[1][1]
			team_200['mid'] = midjg[0][1]
			team_100['jungle'] = midjg[3][1]
			team_100['mid']=midjg[2][1]
		else:
			return -1
	else:
		return 0


	if len(bot)==5:
		if bot[0][0]==100 and bot[1][0]==100 and bot[2][0]==200 and bot[3][0]==200:
			team_100['adc']=bot[0][1]
			team_100['sup'] = bot[1][1]
			team_200['adc'] = bot[2][1]
			team_200['sup']=bot[3][1]
		elif bot[0][0]==200 and bot[1][0]==200 and bot[2][0]==100 and bot[3][0]==100:
			team_200['adc']=bot[0][1]
			team_200['sup'] = bot[1][1]
			team_100['adc'] = bot[2][1]
			team_100['sup']=bot[3][1]
		else:
			return -1
	else:
		return 0

	thisgame['team_blue']=team_100
	thisgame['team_red']=team_200
	if top[-1]==200:
		thisgame['winteam']='red'
	else:
		thisgame['winteam']='blue'

	thisgame['gameid']=gameid
	#print('@'*100)
	for i in list(thisgame.keys()):
		if i=='winteam':
			print(i,thisgame[i],end=', ')
		else:
			print(i,thisgame[i])
	print('@'*100)
	try:
		new_before = load_json('new_before')
	except:
		write_json('new_before',[])
		new_before = load_json('new_before')
	new_before.append(thisgame)
	write_json('new_before',new_before)

#new_before.json

-이런식으로 저장됩니다.

-{팀별 챔피언, 승리팀, gameid}딕셔너리를 모아둔 리스트 형식입니다.

-잘 안보여서 두 게임에 대해서만 시작과 끝을 표시해봤습니다. 우측에 스크롤의 크기를 보시면 참 많은 데이터가 저장되어있음을 알 수 있죠? 포스팅하면서 오늘 하루 켜둔건데도 꽤 많이 모여 뿌듯합니다. ㅎㅎ

 


 #start()

 

 모든 코드는 start() 하에서 돌아갑니다.

  1. 롤 기본정보 수집: phase1()
  2. key에 문제 있으면 메일로 문제가 있음을 알리고 새 key가 수신될 때까지 대기: get_key_from_mail()
    key에 문제 없으면 다음 과정으로
  3. 유저 리스트 작성: get_4000()
  4. 유저 리스트에 있는 유저들의 게임 기록 수집하여 new_before 작성
  5. 1000개의 게임이 기록될 때마다(문제가 없는 게임만 기록됨) 메일로 백업자료 전송: collect(), send_before()

 2~5를 무한반복하며 계속 자료를 수집할 수 있습니다. 남는 컴퓨터가 있다면 집에 수집기를 켜두고, key 교체도 메일로 외부에서 하면서 계속 데이터를 수집할 수 있습니다.

def start():
	global quit_sign
	#롤 기본정보 수집//버전, 패치별 코드 수정 필요
	phase1()
	while True:
		count = 0
		#key에 문제가 생기면 여기서 처리
		if quit_sign==1:
			while True:
				success = get_key_from_mail()
				if success==1:
					quit_sign=0
					send_before()
					break
				else:
					print("key 교체 대기중",end=' ')
					now = datetime.datetime.now()
					print(now)
					time.sleep(10)
		

		#key에 문제 없으면 시작
		#1. 유저 리스트를 만든다 4000명, 셔플
		try:
			user_list = get_4000("GOLD")
		except:
			continue

		#2. 각 유저별 가장 최근 게임이면서 이번 게임 버전에 맞는 게임이라면 분석하여 new_before에 기록
		for user in user_list:
			try:
				collect(user)
			except:
				if quit_sign==1:
					break
				else:
					continue
			#try절에 문제 없으면 else문도 실행됨//1000개 자료 기입시마다 1번씩 메일로 백업
			else:
				count+=1
				if count==1000:
					g_backup = load_json('gameids')
					write_json('backup_gameids',g_backup)
					backup = load_json('new_before')
					write_json('backup_new_before',backup)

					send_before()
					print('백업완료, 메일완료')
					count=0