파이썬

파이썬으로 서든어택 데이터 수집: 병영수첩 전적 크롤링

박범준2 2020. 10. 12. 09:00
반응형

서든어택 크롤링

서든어택 전적을 크롤링하여, csv 파일로 저장합니다.

 

아래 이미지의 빨간 박스 안의 데이터를 수집합니다.

서든어택 병영수첩

수집한 데이터를 아래 이미지의 csv 파일로 저장합니다.  

전적 기록


selenium 패키지를 사용하기 때문에 크롬 웹드라이버가 필요합니다. 

 

파이썬으로 쿠팡 로그인

쿠팡 자동 로그인 파이썬과 selenium을 사용하여 자동으로 쿠팡에 로그인하는 방법입니다. 먼저 selenium을 사용하려면 크롬 웹드라이버가 필요하기 때문에, 다운로드해야 합니다. 크롬 웹드라이버

95pbj.tistory.com

위의 글을 참고하여, 크롬 웹드라이버를 다운로드할 수 있습니다.

 

코드1

필요한 라이브러리를 호출하고, 함수를 선언하는 부분입니다.

import csv
import time
from datetime import datetime, timedelta

from selenium import webdriver


def handle_data(row):
    """병영수첩 전투기록 table의 row를 csv에 쓰기 위한 형태로 변환한다."""
    text = row.text.split("\n")
    date = handle_date(text[0])
    match_map = text[1]
    match_type = text[2]
    cnt_people = text[3]
    result = text[4]
    kill = text[5]
    death = text[7]
    headshot = text[9]
    damage = text[11]
    assist = text[13]
    k_d_ratio = handle_kill_death_ratio(kill, death)
    return date, match_map, match_type, cnt_people, result, kill, death, headshot, damage, assist, k_d_ratio
    
def handle_kill_death_ratio(kill, death):
    """킬뎃을 계산한다."""
    try:
        return round(int(kill) / (int(kill)+int(death)), 2)
    except ZeroDivisionError:
        return 0.00

def handle_date(text):
    """n일 전 형식의 데이터를 yy-mm-dd로 변환한다."""
    date = text.replace("일 전","")
    date = datetime.today() - timedelta(int(date))
    date = date.strftime("%y-%m-%d")
    return date

def get_nickname():
    """닉네임을 가져온다."""
    nick_name = driver.find_element_by_css_selector("div.nickname").text
    return nick_name

def get_match_history():
    """매치기록을 가져온다."""
    history = driver.find_elements_by_css_selector("div.accordion")
    return history

def scroll_down():
    """매치기록을 가져오기 위해, 페이지 하단으로 스크롤한다."""
    SLEEP_TIME = 0.5
    
    last_height = driver.execute_script("return document.body.scrollHeight")
    while True:
        driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
        time.sleep(SLEEP_TIME)
        new_height = driver.execute_script("return document.body.scrollHeight")
        if new_height == last_height:
            break
        last_height = new_height

 

코드2

데이터를 가져올 계정을 리스트 형태로 넣어줍니다.

 

url에서 계정의 고유값으로 추정되는 숫자입니다.

 

계정 하나만 수집한다면 리스트에 값을 하나 넣으시고, 여러 계정을 수집한다면, 전부 명시해주시면 됩니다. 

 

아래 코드에서 account_2, account_3를 계정 고유값으로 바꿔주세요.

# account를 넣어줍니다. ex. "1291934639", "22222", "33123123"
account_list = ["1291934639", "account_2", "account_3"]  

 

 

코드3

데이터를 수집하는 영역의 코드입니다.

 

크롬드라이버는 이 코드 파일과 동일한 경로에 있어야 합니다.

options = webdriver.ChromeOptions()
options.add_argument("headless")
options.add_argument("disable-gpu")
options.add_argument("user-agent=Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36")

driver = webdriver.Chrome("./chromedriver", chrome_options=options)  #크롬드라이버는 같은 폴더에 있어야 한다.

with open("result_" + str(datetime.today().strftime("%y%m%d")) + ".csv", "a", encoding = "cp949") as f:
    f.write("닉네임, 날짜, 맵, 매치유형, 매치인원, 매치결과, 킬, 데스, 헤드샷, 대미지, 어시스트, K/D비율" + "\n")
    wr = csv.writer(f)

    for account in account_list:
        print(account)
        
        url = "http://barracks.sa.nexon.com/" + account + "/match"
        driver.get(url)

        scroll_down()
        
        #크롤링
        nickname = get_nickname()
        history = get_match_history()

        #파일쓰기
        for row in history:
            data_list = list(handle_data(row))
            wr.writerow([nickname] + data_list)
            
driver.quit()

print("\ncomplete")

 

코드 전체

import csv
import time
from datetime import datetime, timedelta

from selenium import webdriver


def handle_data(row):
    """병영수첩 전투기록 table의 row를 csv에 쓰기 위한 형태로 변환한다."""
    text = row.text.split("\n")
    date = handle_date(text[0])
    match_map = text[1]
    match_type = text[2]
    cnt_people = text[3]
    result = text[4]
    kill = text[5]
    death = text[7]
    headshot = text[9]
    damage = text[11]
    assist = text[13]
    k_d_ratio = handle_kill_death_ratio(kill, death)
    return date, match_map, match_type, cnt_people, result, kill, death, headshot, damage, assist, k_d_ratio
    
def handle_kill_death_ratio(kill, death):
    """킬뎃을 계산한다."""
    try:
        return round(int(kill) / (int(kill)+int(death)), 2)
    except ZeroDivisionError:
        return 0.00

def handle_date(text):
    """n일 전 형식의 데이터를 yy-mm-dd로 변환한다."""
    date = text.replace("일 전","")
    date = datetime.today() - timedelta(int(date))
    date = date.strftime("%y-%m-%d")
    return date

def get_nickname():
    """닉네임을 가져온다."""
    nick_name = driver.find_element_by_css_selector("div.nickname").text
    return nick_name

def get_match_history():
    """매치기록을 가져온다."""
    history = driver.find_elements_by_css_selector("div.accordion")
    return history

def scroll_down():
    """매치기록을 가져오기 위해, 페이지 하단으로 스크롤한다."""
    SLEEP_TIME = 0.5
    
    last_height = driver.execute_script("return document.body.scrollHeight")
    while True:
        driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
        time.sleep(SLEEP_TIME)
        new_height = driver.execute_script("return document.body.scrollHeight")
        if new_height == last_height:
            break
        last_height = new_height
        

# account를 넣어줍니다. ex. "1291934639", "22222", "33123123"
account_list = ["1291934639", "account_2", "account_3"]


options = webdriver.ChromeOptions()
options.add_argument("headless")
options.add_argument("disable-gpu")
options.add_argument("user-agent=Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36")

driver = webdriver.Chrome("./chromedriver", chrome_options=options)  #크롬드라이버는 같은 폴더에 있어야 한다.

with open("result_" + str(datetime.today().strftime("%y%m%d")) + ".csv", "a", encoding = "cp949") as f:
    f.write("닉네임, 날짜, 맵, 매치유형, 매치인원, 매치결과, 킬, 데스, 헤드샷, 대미지, 어시스트, K/D비율" + "\n")
    wr = csv.writer(f)

    for account in account_list:
        print(account)
        
        url = "http://barracks.sa.nexon.com/" + account + "/match"
        driver.get(url)

        scroll_down()
        
        #크롤링
        nickname = get_nickname()
        history = get_match_history()

        #파일쓰기
        for row in history:
            data_list = list(handle_data(row))
            wr.writerow([nickname] + data_list)
            
driver.quit()

print("\ncomplete")
반응형