피파온라인4 기록 기반으로 23TOTY 명단 가상 선정하기(1)

khkwon_0712·2023년 2월 9일
0

얼마 전에 23TOTY(2023 Team Of The Year) best 11이 발표되었다. 선정 방법은 23TOTY 선정 자격을 갖춘 100명의 후보 선수들 중에서 팬들의 투표율이 높은 순으로 FW에서 3명, MF에서 3명, DF에서 4명, GK 1명 선정하는 방식이다.

반면에 나는 실제 축구선수들에게 평점을 매기는 방식을 도입하여 각 플레이별 가중치를 설정하고 이를 이용하여 선수들에게 평점을 매긴 후 포지션별로 평점 상위권의 선수들을 골라 23TOTY 명단을 가상으로 선정할 계획이다. 가중치 선정 시에는 AHP 방식으로 포지션별 가중치를 선정한 논문을 참고하였고, 가중치를 적용하여 선수별 평점을 실제로 매긴 자료가 있는 논문 또한 참고하였다. 그리고 피파온라인4 홈페이지에도 선수별로 슛,드리블,패스 등 세부 스텟에 대한 정보들을 제공해주므로 이를 활용하여 선수별로 평점을 매길 수 있었다.

1. 선수 명단 추출하기

피파온라인4 공지를 통해 23TOTY 후보 명단 100명이 발표되었다. 이 선수들을 대상으로 데이터를 분석한다. Selenium을 활용하여 선수 명단을 가져오고, 포지션별로 리스트에 저장한다.

# 23 Team Of The Year 후보 명단 추출

forward_list = []
midfielder_list = []
defender_list = []
goalkeeper_list = []

tbody = '#view > div > section > div.content_body > div.article > div > table > tbody >'

for i in range(2, 36):
    forward = driver.find_element(By.CSS_SELECTOR, tbody + 'tr:nth-child('+str(i)+') > td:nth-child(1) > p').text
    forward_list.append(forward)
    
for j in range(2, 33):
    midfielder = driver.find_element(By.CSS_SELECTOR, tbody + 'tr:nth-child('+str(j)+') > td:nth-child(4) > p').text
    midfielder_list.append(midfielder)
    
for k in range(2, 27):
    defender = driver.find_element(By.CSS_SELECTOR, tbody + 'tr:nth-child('+str(k)+') > td:nth-child(7) > p').text
    defender_list.append(defender)
    
for m in range(2, 12):
    goalkeeper = driver.find_element(By.CSS_SELECTOR, tbody + 'tr:nth-child('+str(m)+') > td:nth-child(10) > p').text
    goalkeeper_list.append(goalkeeper)

print(forward_list)
print(midfielder_list)
print(defender_list)
print(goalkeeper_list)

2. 선수 기록 추출하기

22TOTY 손흥민 선수정보를 확인할 수 있는 페이지에는 다음과 같이 선수의 상세 기록을 확인할 수 있는 정보란이 존재한다.

이렇게 시즌 별로 정보를 추출하여 모두 합산한다. 예를 들어 cap 손흥민 20경기 10골 5도움, 22TOTS 손흥민 10경기 10골 3도움이면 합산 후 30경기 20골 8도움으로 계산한다.
하지만, 일일이 페이지에 들어가서 정보를 입력하는 건 비효율적인 방식이므로 여기서도 크롤링을 적용한다. 선수 정보 페이지 URL을 확인해보면 URL 마지막에 spid=OOOOOOOOO 이렇게 선수 고유의 아이디가 존재한다. 선수 고유 아이디는 api key를 활용하여 불러올 수 있다.

api_key = '발급받은 api key'

headers = {'Authorization' : api_key}
spid_url = requests.get('https://static.api.nexon.co.kr/fifaonline4/latest/spid.json',headers=headers)
spid_parsed_data = spid_url.json()
spid_data = pd.DataFrame(spid_parsed_data,index=[i for i in range(len(spid_parsed_data))])
id_list = spid_data[spid_data['name']=='손흥민']['id'].values.tolist()
print(id_list) # 손흥민 시즌 id 모음 리스트
[201200104, 206200104, 207200104, 215200104, 221200104, 222200104, 230200104, 234200104, 240200104, 250200104, 252200104, 258200104, 267200104, 273200104, 278200104, 293200104, 295200104, 298200104, 300200104, 500200104, 501200104, 502200104, 503200104, 506200104, 508200104, 511200104]

위의 코드를 실행하면 손흥민 시즌들의 spid들을 전부 리스트에 저장한다. 이 리스트에 존재하는 spid들을 반복문을 활용하여 URL을 반복적으로 수정하여 선수의 정보들을 추출한다. 골, 도움 이외에도 패스, 드리블, 슛, 공중볼, 가로채기, 태클, 차단, 선방 등의 데이터를 선수별로 추출하고 이를 합산하여 저장한다.

(데이터프레임으로 저장하고 이름 기준으로 groupby 함수를 활용하여 묶으면 기록이 합산된다)

column과 데이터 행이 주어지면, 이름이 같은 행끼리 묶으면 합산되는 원리이다.

column의 내용과 데이터가 일치하도록 순서에 유의해야 한다.

columns = ['이름','출전','득점','도움','유효 슈팅','일반 슈팅','패스 성공 횟수','전체 패스 횟수','드리블 성공 횟수','전체 드리블 횟수',
           '공중볼 경합 성공 횟수','전체 공중볼 경합 횟수','가로채기','태클 성공 횟수','전체 태클 횟수','차단 성공 횟수',
           '전체 차단 횟수','선방(골 차단)']

column은 다음과 같이 설정하였다.

ex) [손흥민, 10, 5, 5] 과 [손흥민, 5, 1, 1] 행이 있으면 이를 합산하여 [손흥민, 15, 6, 6]과 같이 합산한다.

이제 합산된 기록을 활용하여 데이터프레임을 사칙연산을 통해 전처리하여 원하는 데이터를 추가하고, MySQL에 저장하는 내용을 다음 포스트에 정리한다.

↓↓ 전체 코드는 github를 참고해주세요😊😊

github 주소 : https://github.com/Kihoon-Kwon/nominate_23toty.git

profile
꾸준하게 😊

0개의 댓글