-
[Crawling Project_급등된 주가에 대한 기사 분석 및 자료 메일링 서비스_최종코드]About_Datascience/Project 2023. 1. 24. 17:35
첫 토이 프로젝트인 크롤링 프로젝트를 진행하였다.
우리 조의 주제는 여러 아이디어가 나왔는데 그 중 '급등된 주가에 대한 기사 분석 및 자료 메일링 서비스' 로 정하였다.
처음에는 네이버 증권 창에서 거래량 상위 종목 중 등락율이 높은 종목들을 크롤링하고 추출된 종목들을 뉴스 검색창에 검색하여
뉴스 제목과 링크를 뽑아와 뼈대를 잡았다. 그 후 차트 이미지 삽입, 자동화,메일링 서비스 등 조건과 기능들을 하나씩 추가하면서
서비스를 디벨롭 시키고자 하였다.
이번 크롤링 프로젝트는 Selenium을 이용하여 진행하였다.
필요한 모듈
from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.common.keys import Keys from selenium.webdriver.common.action_chains import ActionChains from IPython.display import Image from PIL import Image #이미지 처리 모듈 import string import requests #웹 접속 모듈 import time import sys import pyperclip # copy() 이용하여 복사 붙여넣기 하는 기능 import getpass as gp #비밀번호 입력할 때 안 보이게 함
최종코드 (이미지 복사 후 붙여넣기 이슈으로 인해 window 환경에서만 실행 가능한 코드)
※ 이미지 관련 내용 이슈는 다음 게시물에서 다루도록 하겠습니다 ! ※
# 원하는 등락률 입력받기 while True: try: want_rate = float(input("등락률 기준을 입력하세요 : ")) if (type(want_rate) == float) or (type(want_rate) == int): break except: print("!!!!!!!!!!!!!!정수나 실수를 입력하세요!!!!!!!!!!!!!!!") while True: # 네이버 아이디 입력받기 user_id = input('아이디를 입력하세요 : ') # 네이버 비밀번호 입력받기 user_pw = input('패스워드를 입력하세요 : ') # 수신 받을 메일 주소 입력 address = input('메일주소를 입력하세요 : ') # 입력받은 내용 확인하기 try: print(f''' ********************************* 아이디 :{user_id} 비밀번호 : {user_pw} 메일주소 : {address} *********************************''') check_id = int(input('위 내용이 일치하면 0 아니면 1입력 : ')) except: print("0이나 1만 입력하세요!!") if check_id == 0: print('메일링 서비스가 시작됩니다') break else: print('정보를 다시 입력해주세요') continue ####################### 증권 페이지 열기 및 코스피, 코스닥 차트를 png파일로 저장 ############################ # 모델 실행 날짜 받아오기 dt = datetime.now() # 모델 실행 날짜 원하는 형태로 변경 nowDate = dt.strftime('%Y-%m-%d') # 네이버 증권 페이지 열기 chrome = webdriver.Chrome('chromedriver') chrome.get('https://finance.naver.com/') # 코스피 차트 저장 kospi_chart = chrome.find_element(By.CSS_SELECTOR, '.kospi_area.group_quot.quot_opn a img') kospi_chart.screenshot(f'{nowDate}일자 kospi.png') # 코스닥 차트 더보기 클릭 kosdac_chart_btn = chrome.find_element(By.CSS_SELECTOR, '.kosdaq_area.group_quot span.clse_bg') kosdac_chart_btn.click() # 코스닥 차트 저장 kospi_chart = chrome.find_element(By.CSS_SELECTOR, '.kosdaq_area.group_quot.quot_opn a img') kospi_chart.screenshot(f'{nowDate}일자 kosdac.png') #################### 거래상위 사이트로 이동 => 코스피, 코스닥 종목명, 등락률 # 거래상위 사이트로 이동 chart_link = chrome.find_element(By.CSS_SELECTOR, '.section_sise_top div a em') chart_link.click() for i in range(5): chrome.execute_script("window.scrollBy(1,document.body.scrollHeight)") time.sleep(1) all_stocks = [] all_rates = [] # 종목명 크롤링 후 이중 리스트로 저장 kospi_name = [] for i in chrome.find_elements(By.CLASS_NAME, 'tltle'): i = i.text kospi_name.append(i) all_stocks.append(kospi_name) # 코스피 등락률 크롤링 후 이중 리스트로 저장 kospi_rate = [] for i in chrome.find_elements(By.CSS_SELECTOR,'td:nth-child(5) span[class$="01"]'): i = i.text kospi_rate.append(i) all_rates.append(kospi_rate) # 코스닥 버튼 찾기 kosdac_btn = chrome.find_element(By.CSS_SELECTOR, '.tab_smeun>a') # 코스닥 넘어가기 kosdac_btn.click() for i in range(5): chrome.execute_script("window.scrollBy(1,document.body.scrollHeight)") time.sleep(1) # 코스닥 종목명 넣기 후 이중 리스트로 저장 kosdac_name = [] for i in chrome.find_elements(By.CLASS_NAME,'tltle'): i = i.text kosdac_name.append(i) all_stocks.append(kosdac_name) # 코스닥 등락률 넣기 후 이중 리스트로 저장 kosdac_rate = [] for i in chrome.find_elements(By.CSS_SELECTOR,'td:nth-child(5) span[class$="01"]'): i = i.text kosdac_rate.append(i) all_rates.append(kosdac_rate) # 특수기호 전처리 real_value =[] all_real_value = [] names_rates = {} # 구분인자 딕셔너리에 넣기 names_rates['코스피']='코스피' for rates in all_rates: all_rates_index = all_rates.index(rates) # %기호 제거하는 전처리 후 실수(float)로 저장 for value in rates: output_value = value.strip("%") output_value=float(output_value) if abs(output_value) >= want_rate: # 5퍼 넘는 애들의 인덱스 찾기 rate_index = rates.index(value) # 5퍼 넘는거 딕셔너리로 이름,등락률 저장 stock_name =all_stocks[all_rates_index][rate_index] names_rates[stock_name]=rates[rate_index] else: continue # 코스피 구분인자 딕셔너리에 넣기 if '코스닥' in names_rates.values(): continue else: names_rates['코스닥']='코스닥' # 증권 뉴스 버튼 찾기 news_btn = chrome.find_element(By.CSS_SELECTOR, 'li.m7 a') # 증권 뉴스 탭으로 넘어가기 news_btn.click() # 뉴스 검색 창 버튼 찾기 search_btn = chrome.find_element(By.CSS_SELECTOR, 'a strong.lst_news9') # 뉴스 검색 창으로 이동 search_btn.click() # 최근 일주일 선택버튼 찾기 direct_input = chrome.find_element(By.ID, "schoption13") #버튼 클릭 direct_input.click() # 추려진 내용 하나씩 꺼내기 news_count_list = [] news_name_url = {} news_name_date = {} for search_name in names_rates.keys(): if (search_name == '코스피') or (search_name == '코스닥'): print(f'{search_name}종목 검색 실행중') else: # 검색이름 클래스 search_input = chrome.find_element(By.CLASS_NAME, 'inputTxt') # 기존에 입력된 내용 지우기 search_input.clear() # 종목명 입력 search_input.send_keys(search_name) # 입력 후 엔터 search_input.send_keys('\n') time.sleep(1) # 기사 개수 변수 num_news = chrome.find_element(By.CSS_SELECTOR, 'p strong:nth-child(2)').text news_count_list.append(num_news) if num_news=='0': continue else: # 뉴스 요소들 추출 new_items = chrome.find_elements(By.CSS_SELECTOR, '.articleSubject > a') # 종목의 이름 및 등락률 # 기사의 개수 출력 news_name_list = [] for item in new_items[0:3]: # 기사 제목 추출 news_name = item.text # 기사 링크 추출 url =item.get_attribute('href') # 기사 날짜 추출 news_date = chrome.find_element(By.CSS_SELECTOR, 'dd span.wdate') news_date = news_date.text[:10] # 기사 제목과 날짜를 딕셔너리로 저장 news_name_date[news_name] = news_date # 기사 제목과 링크 리스트로 묶어서 저장하기 news_name_list.append([news_name, url]) # 기사 제목과 링크 리스트를 value, 종목명을 key로 해서 딕셔너리 저장 news_name_url[search_name] = news_name_list # 네이버 홈 버튼 찾기 home = chrome.find_element(By.CSS_SELECTOR, 'h1.logo') # 네이버 홈 버튼 클릭 home.click() # 요소 찾을 때 기다리기 chrome.implicitly_wait(10) # 로그인 버튼 찾기 login_link = chrome.find_element(By.CLASS_NAME, 'link_login') # 로그인 버튼 클릭 login_link.click() # 아이디 입력칸 input_id = chrome.find_element(By.ID, 'id') # 비밀번호 입력칸 input_pw = chrome.find_element(By.ID, 'pw') # 자동입력방지 피하기 pyperclip.copy(user_id) input_id.send_keys(Keys.CONTROL, "v") pyperclip.copy(user_pw) input_pw.send_keys(Keys.CONTROL, "v") # 로그인 버튼 클릭 # kospi 차트 다운받은거 불러오기 login_btn = chrome.find_element(By.ID, "log.login") login_btn.click() # 메일 버튼 클릭 time.sleep(3) mail_btn = chrome.find_element(By.CSS_SELECTOR, 'li.nav_item') mail_btn.click() # 메일 쓰기버튼 클릭 write_mail = chrome.find_element(By.CSS_SELECTOR, 'a.button_write') write_mail.click() # 받은 메일주소 입력하기 input_address = chrome.find_element(By.CSS_SELECTOR, '#user_input_1') input_address.send_keys(address) # 메일 제목 입력 title_name = chrome.find_element(By.ID,'subject_title') title_name.send_keys(f'{nowDate} 코스피 & 코스닥 인기종목 등락률 자동화 메일!!!!!') # 메일 내용 입력 프레임으로 옮기기 chrome.switch_to.frame(chrome.find_element(By.XPATH, '//*[@id="content"]/div[3]/div/div[2]/div/div[3]/iframe')) input_sum = chrome.find_element(By.XPATH,'/html/body/div/div[1]') input_sum.click() # 메일 내용 작성하기 for key,value in names_rates.items(): if (key == '코스피') or (key == '코스닥'): ################# 이미지 파일을 => 복사해서 클립보드에 저장 def send_to_clipboard(clip_type, data): win32clipboard.OpenClipboard() win32clipboard.EmptyClipboard() win32clipboard.SetClipboardData(clip_type, data) win32clipboard.CloseClipboard() input_sum.send_keys(f''' {key}의 현재 차트 ''') if key == '코스피': filepath = f'{nowDate}일자 kospi.png' else: filepath = f'{nowDate}일자 kosdac.png' image = Image.open(filepath) output = BytesIO() image.convert("RGB").save(output, "BMP") data = output.getvalue()[14:] output.close() send_to_clipboard(win32clipboard.CF_DIB, data) ################# actions = ActionChains(chrome) actions.key_down(Keys.CONTROL).send_keys('v').key_up(Keys.CONTROL).perform() time.sleep(5) input_sum.send_keys(f''' ----------------------------------------{key}---------------------------------------- ''') elif key not in news_name_url: continue else: input_sum.send_keys(f''' 종목명 : [ {key} ] & 등락률 [ {value} ] {key}과 관련된 일주일간 총 1~5개의 기사 제목 및 링크 **************************************************************************************** ''') count = 0 for title_url in news_name_url[key]: title = title_url[0] url = title_url[1] count+=1 input_sum.send_keys(f''' {count}. 뉴스제목 ({news_name_date[title]}) : {title} => 기사링크 : {url}''') input_sum.send_keys(''' **************************************************************************************** ''') # 다시 부모 프레임으로 옮기기 chrome.switch_to.default_content() # 메일 보내기 버튼 누르기 task_btn = chrome.find_element(By.CSS_SELECTOR, 'button.button_write_task') task_btn.click() time.sleep(3) chrome.quit()
'About_Datascience > Project' 카테고리의 다른 글
[Crawliing Project _ 회고_ 어려웠던 부분(2) 이미지 복사 후 삽입] (0) 2023.01.24 [Crawliing Project _ 회고_ 어려웠던 부분(1) iframe안으로 이동] (0) 2023.01.24