본문 바로가기

FootballAnalysis

[K리그 데이터 분석] 1. K리그 데이터 포털 크롤러 구현

 

K리그 축구 전문 데이터 포털

K리그의 모든 것이 담겨있습니다. 경기전 관전포인트 부터 전문 분석 매치서머리까지 지금 방문해보세요. 로그인 없이 이용하실 수 있습니다.

data.kleague.com

 

 

첫번째 포스팅 겸 포트폴리오 준비로 K리그 매치 데이터를 양적 데이터 분석을 위해 크롤링하여 분석 가능한 형식으로 변환하는 파이프라인을 구현해보려고 한다.  이런 걸 데이터 파이프라인이라고하면 데이터 엔지니어분들이 화내실거 같아서...

 

seleniumbs4를 처음 배울 때에는 By.IDBy.CSS_SELECTOR 등을 이용하여 크롤링 코드를 작성했다.

하지만, 해당 페이지의 경우 Javascript 함수로 페이지 요소가 변경되는 방식이라 새로운 방법을 찾아야 했고,

driver.excute_script로 데이터 센터에 접속할 수 있었다.

from selenium import webdriver
chrome_options = webdriver.ChromeOptions()
driver = webdriver.Chrome(options=chrome_options)

driver.execute_script("moveMainFrame('0000');")

이후에는 기존에 공부했던 내용으로 순조롭게 데이터를 크롤링 해왔지만

K리그 데이터 포털 - 데이터센터 - 부가기록

데이터의 일부 column name이 html에 두개의 행으로 나누어져 특정 column 하나에 세 개의 하위 column name을 가지고 있어서 크롤링한 데이터로 데이터프레임을 만들면 분석이 불가능한 형태로 만들어졌다.

data = [
    "년도,선수명,포지션,등번호,출전시간(분),"
    "득점,도움,슈팅,유효 슈팅,차단된슈팅,벗어난슈팅,PA내 슈팅,PA외 슈팅,"
    "오프사이드,프리킥,코너킥,스로인,"
    "드리블 시도,드리블 성공,드리블 성공%,"
    "패스 시도,패스 성공,패스 성공%,키패스,전방 패스 시도,전방 패스 성공,전방 패스 성공%,후방 패스 시도,후방 패스 성공,후방 패스 성공%,"
    "횡패스 시도,횡패스 성공,횡패스 성공%,"
    "공격지역패스 시도,공격지역패스 성공,공격지역패스 성공%,수비지역패스 시도,수비지역패스 성공,수비지역패스 성공%,"
    "중앙지역패스 시도,중앙지역패스 성공,중앙지역패스 성공%,롱패스 시도,롱패스 성공,롱패스 성공%,중거리패스 시도,중거리패스 성공,중거리패스 성공%,"
    "숏패스 시도,숏패스 성공,숏패스 성공%,크로스 시도,크로스 성공,크로스 성공%,"
    "경합 지상 시도,경합 지상 성공,경합 지상 성공%,경합 공중 시도,경합 공중 성공,경합 공중 성공%,태클 시도,태클 성공,태클 성공%,"
    "클리어링,인터셉트,차단,획득,블락,볼미스,파울,피파울,경고,퇴장"
]

columns = data[0].split(",")
if table:  # 테이블이 존재하는 경우에만 처리
        rows = table.find_all('tr')
        for row in rows[2:-1]:
                cols = row.find_all(['td', 'th'])  # 'td'와 'th' 모두 찾기
            cols = [ele.text.strip() for ele in cols]  # 텍스트를 추출하고 공백 제거
            data.append(cols)

 

이를 방지하고자 data 에 하위 column name을 병합하여 새로운 column name을 3개씩 만들어 1행에 저장했으며, 크롤링 코드에 슬라이싱을 이용하여 html 리소스를 column name이 있는 두 행을 제외하고 크롤링하였다.

 

성공적으로 크롤링된 데이터는 csv파일로 저장하였다.

    output_file = f"data/k-league-data-{datetime.now().strftime('%Y%m%d-%H%M')}.csv"
    with open(output_file, mode='w', newline='', encoding='utf-8-sig') as file:
        writer = csv.writer(file)
        writer.writerow(columns)  # 컬럼 이름 작성
        writer.writerows(data[1:])  # 데이터 작성
    print(f"Data has been written to {output_file}")

 

크롤링을 통해 데이터를 수집할 수 있지만 K리그가 한 라운드 진행될 때마다 직접 코드를 실행해야 데이터가 최신화된다는 단점이 존재한다.

이를 해결하기 위한 방안을 모색해 볼 필요가 있다.

 

TODO:

K리그가 한 라운드 진행될 때마다 주기적으로 데이터를 수집하여 최신화하는 기능을 추가한다.

분석에 용이하도록 데이터 형식을 바꾼다.

 

 

전체 소스 코드는 여기서 확인하실 수 있습니다.

 

GitHub - jeongbeenson19/K-league-pipeline-project

Contribute to jeongbeenson19/K-league-pipeline-project development by creating an account on GitHub.

github.com