과거 원하는 1달 국내주식 시가총액 1~50위까지 순위를 자동화로 추출하여 엑셀에 저장하는 코드입니다.
시가총액 데이터는 한국거래소 사이트 URL을 통해 데이터를 추출합니다.
http://data.krx.co.kr/contents/MMC/RANK/rank/MMCRANK001.cmd
추출하고 싶은 년도 / 월을 콘솔에서 입력 받아 현재 날짜와의 차이를 통해 달력을 이동하여 특정 달 화면으로 이동합니다.
input_year = input("년도를 입력하세요. : ")
input_month = input("월을 입력하세요. : ")
driver.find_element(By.CLASS_NAME, 'CI-CAL-OPEN-BTN').click()
time.sleep(2)
cal_text = driver.find_element(By.CLASS_NAME, 'calTit').text #현재 년월 데이터 얻기
year_text = cal_text[:4]
month_text = cal_text[-2:]
year_dif = int(year_text) - int(input_year) #원하는 년도 차이 구하기
month_dif = int(month_text) - int(input_month) #원하는 월 차이 구하기
find_elements() a 태그로 추출한 후 원하는 날짜를 클릭할 수 있는 함수를 작성하였습니다.
def date_click(num): #원하는 날 날짜를 설정하는 함수
if num != 0:
driver.execute_script('window.scrollTo(0, 0)')
driver.find_element(By.CLASS_NAME, 'CI-CAL-OPEN-BTN').click()
cal_date = driver.find_element(By.CLASS_NAME, 'calendarWrap').find_elements(By.TAG_NAME, 'a')
cal_date[num].click()
time.sleep(1)
driver.find_element(By.CLASS_NAME, 'CI-CAL-CONFIRM-BTN').click()
time.sleep(2)
driver.find_element(By.ID, 'jsSearchButton').click()
time.sleep(2)
1~50위 순위를 보기 위해서 스크롤 처리가 필요하였는데 페이지 내 표를 따로 스크롤해야 해서 일반적인 방법으로는 실패하였습니다.
여러가지 방법을 찾던 중 해당 표를 선택한 후 스크롤을 내리는 방법으로 구현을 선택하였습니다.
ActionChain 내 drag_and_drop 기능을 사용하여 해당 표를 선택한 후 pyautogui 키보드 동작으로 표를 움직일 수 있게 코드를 작성하였습니다.
def data_scroll(num): #데이터 추출을 위해 스크롤 처리를 하는 함수
elements = driver.find_elements(By.CLASS_NAME, 'tui-grid-cell-content')
drag = elements[35]
drop = elements[37]
action.drag_and_drop(drag, drop).perform()
for i in range(0, num):
pyautogui.press('down')
time.sleep(2)
표에 있는 데이터를 추출하여 리스트에 저장하는 함수를 작성하였습니다.
def data_add(x, y): #추출한 데이터를 추가하는 함수
elements = driver.find_elements(By.CLASS_NAME, 'tui-grid-cell-content')
for i in range(x, 38):
if i % 2 != 0:
stock_name.append(elements[i].text)
for i in range(y, 170, 7):
stock_price.append(elements[i].text)
스크롤 함수와 데이터 추가 함수를 반복 사용하여 1일치 1~50위 시가 총액 순위를 추출하는 함수를 작성하였습니다.
def daily_data(): #1일치 데이터를 추가하여 엑셀에 저장하는 함수
stock_name = []
stock_price = []
number = 1
data_add(1, 39)
data_scroll(19)
data_add(3, 48)
data_scroll(14)
data_add(13, 81)
wb.create_sheet('test2')
ws = wb['test2']
ws.title = driver.find_element(By.ID, 'trdDd').get_attribute('value') # 시트 타이틀 설정
ws.append(['순위', '종목', '종가']) # 첫 행에 저장할 데이터 항목 추가
for i in range(len(stock_name)):
ws.append([number, stock_name[i], stock_price[i]])
number += 1
wb.save('/Users/user/Desktop/stock.xlsx') # 해당 경로에 엑셀 파일 저장
1달치를 뽑기 위해 1일치 함수를 일자만큼 반복하는 코드를 작성하였습니다.
for i in range(len(cal_date)): #해당 월에 있는 일자만큼 반복하여 데이터 추출
date_click(i)
daily_data()
전체 코드입니다. 해당 코드를 통해 1달치 데이터를 추출하여 엑셀하여 결과를 얻을 수 있습니다.
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from selenium.webdriver import ActionChains
from webdriver_manager.chrome import ChromeDriverManager
import time
import pyautogui
from openpyxl import Workbook
input_year = input("년도를 입력하세요. : ")
input_month = input("월을 입력하세요. : ")
driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()))
driver.get('http://data.krx.co.kr/contents/MMC/RANK/rank/MMCRANK001.cmd')
time.sleep(2)
driver.maximize_window() #현재 브라우저 창 최대로 키우기
driver.find_element(By.CLASS_NAME, 'CI-CAL-OPEN-BTN').click()
time.sleep(2)
cal_text = driver.find_element(By.CLASS_NAME, 'calTit').text #현재 년월 데이터 얻기
year_text = cal_text[:4]
month_text = cal_text[-2:]
year_dif = int(year_text) - int(input_year) #원하는 년도 차이 구하기
month_dif = int(month_text) - int(input_month) #원하는 월 차이 구하기
for i in range(year_dif):
driver.find_element(By.CLASS_NAME, 'prevYear').click()
time.sleep(1)
for i in range(abs(month_dif)):
if month_dif > 0:
driver.find_element(By.CLASS_NAME, 'prevMonth').click()
else:
driver.find_element(By.CLASS_NAME, 'nextMonth').click()
time.sleep(1)
action = ActionChains(driver)
wb = Workbook() # Workbook 생성
cal_date = driver.find_element(By.CLASS_NAME, 'calendarWrap').find_elements(By.TAG_NAME, 'a')
stock_name = []
stock_price = []
def date_click(num): #원하는 날 날짜를 설정하는 함수
if num != 0:
driver.execute_script('window.scrollTo(0, 0)')
driver.find_element(By.CLASS_NAME, 'CI-CAL-OPEN-BTN').click()
cal_date = driver.find_element(By.CLASS_NAME, 'calendarWrap').find_elements(By.TAG_NAME, 'a')
cal_date[num].click()
time.sleep(1)
driver.find_element(By.CLASS_NAME, 'CI-CAL-CONFIRM-BTN').click()
time.sleep(2)
driver.find_element(By.ID, 'jsSearchButton').click()
time.sleep(2)
def data_scroll(num): #데이터 추출을 위해 스크롤 처리를 하는 함수
elements = driver.find_elements(By.CLASS_NAME, 'tui-grid-cell-content')
drag = elements[35]
drop = elements[37]
action.drag_and_drop(drag, drop).perform()
for i in range(0, num):
pyautogui.press('down')
time.sleep(2)
def data_add(x, y): #추출한 데이터를 추가하는 함수
elements = driver.find_elements(By.CLASS_NAME, 'tui-grid-cell-content')
for i in range(x, 38):
if i % 2 != 0:
stock_name.append(elements[i].text)
for i in range(y, 170, 7):
stock_price.append(elements[i].text)
def daily_data(): #1일치 데이터를 추가하여 엑셀에 저장하는 함수
stock_name = []
stock_price = []
number = 1
data_add(1, 39)
data_scroll(19)
data_add(3, 48)
data_scroll(14)
data_add(13, 81)
wb.create_sheet('test2')
ws = wb['test2']
ws.title = driver.find_element(By.ID, 'trdDd').get_attribute('value') # 시트 타이틀 설정
ws.append(['순위', '종목', '종가']) # 첫 행에 저장할 데이터 항목 추가
for i in range(len(stock_name)):
ws.append([number, stock_name[i], stock_price[i]])
number += 1
wb.save('/Users/user/Desktop/stock.xlsx') # 해당 경로에 엑셀 파일 저장
for i in range(len(cal_date)): #해당 월에 있는 일자만큼 반복하여 데이터 추출
date_click(i)
daily_data()
wb.remove(wb['Sheet']) #기존에 있는 Sheet 삭제
wb.save('/Users/user/Desktop/stock.xlsx')
print('Excel Save Complete!!!')
driver.quit()
해당 코드를 통해 2022년 2월 시가총액 데이터를 뽑은 결과입니다. 1일마다 시트를 따로 생성하여 데이터를 구분하였습니다.
'자동화 > Selenium' 카테고리의 다른 글
KFC 설문조사 Selenium으로 자동화하기 (0) | 2022.12.06 |
---|---|
핫딜게시판 목록 리스트 자동화하여 추출 (0) | 2022.11.08 |
웹 크롤링으로 iOS 앱스토어 리뷰 Excel에 저장하기 (With Python) (0) | 2022.11.01 |
웹 크롤링으로 플레이스토어 리뷰 Excel에 저장하기 (With Python) (1) | 2022.10.30 |
버거킹 설문조사 Selenium으로 자동화하기 (0) | 2022.10.27 |