[Python] 슬랙(Slack) 알림봇 설정하여 매일 증시 알림 받기 (3) - 1
프로젝트/[ed]_슬랙봇_증시알림

[Python] 슬랙(Slack) 알림봇 설정하여 매일 증시 알림 받기 (3) - 1

728x90
반응형

앞선 포스팅에 계속하여 슬랙 알림봇이 매일매일 증시정보를 가져와서 알려주게끔 웹스크래이핑 기능을 더해보겠습니다. 3-1 에선 웹스크래이핑 하고 읽는 함수를 만들고, 3-2에서는 3-1 의 함수를 (2) 에서 작성한 코드에서 불러와 매일 증시정보를 알려주는 봇으로 만들겠습니다.

 

웹스크래이핑은 파이썬으로 할 예정입니다. 파이썬에서의 웹스크래이핑은 정적페이지를 크롤링하는 Beautiful Soup 모듈, 동적페이지를 크롤링하는 Selenium 모듈로 크게 구분할 수 있습니다. 여기선 Beautiful Soup 으로 크롤링 하겠습니다.

 

(필요모듈 : Beautiful Soup, requests

없다면, 커맨드창에 pip install bs4 / pip install requests 를 입력하여 설치)

 

크롤링할 주소는 네이버 금융의 코스피 화면에서 이미지, 등락값, 투자자별 매매동향, 프로그램 매매 동향 입니다. (https://finance.naver.com/sise/sise_index.naver?code=KOSPI)

 

크롤링할 사이트 및 가져올 데이터들 (빨강 박스)

 

이제 F12를 눌러서 해당 위치가 어디인지 확인합니다.

(** 사용한 브라우저는 구글 크롬입니다. F12 : 개발자도구 버튼으로 해당 사이트의 소스가 표시됩니다. 물론 마우스 우클릭 → 소스보기(단축키 : ctrl + u) 를 하셔도 됩니다. 그렇지만 개발자도구를 써서보면 해당 소스코드가 홈페이지 어디에 위치하는지 시각적으로 보여주므로 찾기 쉬우니 개발자도구를 활용하시는 걸 추천드립니다.)

 

개발자도구(F12) 를 썻을때. 소스코드와 사이트 비교가 편하다.

 

단순 소스보기(ctrl + U) 를 눌렀을 때. 일일이 찾아야 되서 불편하다.

 

원하는 요소들은 각각 아래의 위치에 있습니다. 

그래프 이미지 주소 :  li id = "chart0" 의 graph 클래스 아래 img src

코스피 값 / 변화량 / 증감률 : <div class="quotient up" id="quotient"> 의 하위항목

(** class 의 경우 상승이면 "quotient up", 하락이면 "quotient dn" 으로 표시된다. )

투자자별, 프로그램 매매동향 : <dl class = "lst_kos_info"> 의 하위항목

 

 

이제 위치를 알았으니 크롤링을 하면 됩니다. 지난번 포스팅에 쓴 파일과 별개의 파일을 하나 만들어 줍니다. 

이 파일에는 크롤링된 정보를 읽을 수 있는 함수를 작성할 예정입니다.

전체 코드는 아래와 같습니다. 

코드의 흐름은 뷰티풀수프로 원하는 주소를 크롤링 → 원하는 값 각각 raw 상태로 추출 → 쓰기좋게 문자열 편집 및 값 리턴 순 입니다.

from bs4 import BeautifulSoup
import requests

def KospiRead():

    url = 'https://finance.naver.com/sise/sise_index.naver?code=KOSPI'
    # 네이버 금융이 헤더를 요구하는 방식으로 바뀌었다. 그래서 헤더가 필요하다.
    headers = # 자기 컴퓨터의 header 입력
    req = requests.get(url, headers = headers)
    soup = BeautifulSoup(req.text, 'lxml')
    
    daily = soup.find('div', class_ = 'graph')
    s = str(daily.img['src']) # 코스피 이미지 파일 주소.

    posts = soup.find('dl', class_ = 'lst_kos_info')
    post_title_1 = posts.find("dt").get_text() # 투자자별 매매동향 텍스트 추출
    post_title_2 = posts.find("dt", class_ = "last").get_text() # 프로그램별 매매동향 텍스트 추출

    trend_value = [] # 개인 , 외국인, 기관, 차익, 비차익, 전체 값
    characters = ",억" # 억으로 표기된 글자를 지우기 위해서 만듬
    operator = []
    i = 0

    for td in posts.parent.find_all('dd'):
        if td.text.find('+') != -1: # 양수
            operator.append('+')
        else: # -1 이 나온경우. 음수임.
            operator.append('-')
        refined_text = ''.join(x for x in str(td.text) if x not in characters)
        trend_value.append(str(refined_text.split(operator[i])[1]))
        trend_value[i] = operator[i] + trend_value[i]
        i = i + 1

    daily2 = soup.find('div', id = "quotient").get_text() # 코스피 현재값, 증감량, 증감률 추출
    a1 = daily2.split('\n')
    a2 = a1[2].split('%')[0]
    
    if a2.find('+') != -1: # + 인 경우
        a4 = '△'
    else:
        a4 = '▽'

    a3 = []
    a3.append(a1[1] + ' ')
    a3.append(a4 + a2 + '%')

    return s, trend_value, a3

 

각 라인별 코드를 설명해보자면 다음과 같다. 

 

from bs4 import BeautifulSoup
import requests

def KospiRead():
	# 크롤링 원하는 주소
    url = 'https://finance.naver.com/sise/sise_index.naver?code=KOSPI' 
    # 자기 컴퓨터의 header 입력.
    headers = # 네이버 금융이 헤더를 요구하는 방식으로 바뀌어 필요
    # url 과 header 정보를 이용하여 해당 사이트에 정보요청
    req = requests.get(url, headers = headers)
    # 정보요청한 것 중, 텍스트 형식으로된 html 소스코드를 뷰티풀수프의 lxml 파서(parser) 으로 처리
    soup = BeautifulSoup(req.text, 'lxml') 
    # ** lxml 형식은 속도가 빠르고 유연한 파싱 (parsing) 이 가능한게 장점.
    
    # 이미지 링크가 있는 곳까지 찾는다. graph class 가 여러개 있긴 하지만, 우리가 원하는건 
    # 맨 앞에 있는 1일단위 그래프이기 때문에 제일 먼저 찾아서 확인이 가능하므로 별개의 처리는 하지 않는다.
    daily = soup.find('div', class_ = 'graph')
    s = str(daily.img['src']) # 코스피 이미지 파일 주소 추출.

 

header 를 확인하는 방법은 아래의 사이트를 클릭하시면 알 수 있습니다.

 

http://m.avalon.co.kr/check.html

 

USER AGENT 확인

navigator.userAgent 값은 다음과 같습니다. $_SERVER['HTTP_USER_AGENT'] 값은 다음과 같습니다.

m.avalon.co.kr

 

 

 

    # 투자자별 매매동향, 프로그램 매매동향을 확인하기 위해 lst_kos_info 클래스를 찾아둔다
    posts = soup.find('dl', class_ = 'lst_kos_info')
    post_title_1 = posts.find("dt").get_text() # 투자자별 매매동향 텍스트 추출
    post_title_2 = posts.find("dt", class_ = "last").get_text() # 프로그램별 매매동향 텍스트 추출

    trend_value = [] # 개인 , 외국인, 기관, 차익, 비차익, 전체 값을 넣을 빈 리스트를 만든다
    characters = ",억" # 억으로 표기된 글자를 지우기 위해서 미리 지정해둔다
    operator = [] # 스크래이핑 및 텍스트 추출이 완료되면 부호가 지워지는데 이걸 다시 살리기 위한 리스트
    i = 0

	# 투자자별 매매동향, 프로그램 매매동향의 값 추출하기 위한 반복문
    for td in posts.parent.find_all('dd'):
    	# 개별 텍스트 추출하기 전, 양수인지 음수인지 미리 확인해둔다.
        if td.text.find('+') != -1: # 양수 ** -1 은 어디에도 없다는걸 의미한다. != -1 은 -1이 아닐 경우. 
            operator.append('+')
        else: # -1 이 나온경우, 음수
            operator.append('-')
        # ,와 억 문자를 뺀 나머지 텍스트로 넣는다
        refined_text = ''.join(x for x in str(td.text) if x not in characters) 
        # + / - 를 기준으로 문자열을 자른다. 그 뒤 뒤에 있는 값만 추출한다.
        trend_value.append(str(refined_text.split(operator[i])[1]))
        trend_value[i] = operator[i] + trend_value[i]
        i = i + 1 # i는 반복문에 대응하는 리스트의 요소를 매치 시키기 위한 값.

 

 

    # 코스피 현재값, 증감량, 증감률 추출. class 가 상승 하강 보합 일 경우 계속 바뀌므로
    # id 로 찾아 대응한다.
    daily2 = soup.find('div', id = "quotient").get_text()  # 코스피 값 텍스트 raw 상태로 추출
    
    # 스페이스로 요소 구분
    a1 = daily2.split('\n')
    # 3번째 요소를 %로 쪼갠다음 왼쪽 문자열 사용
    a2 = a1[2].split('%')[0]
    
    # + / - 에 따라 놓친 삼각형 기호를 넣어주는 if 문
    if a2.find('+') != -1: # + 인 경우
        a4 = '△'
    else: # - 인 경우
        a4 = '▽'

    a3 = []
    a3.append(a1[1] + ' ')
    a3.append(a4 + a2 + '%') # 완성된 문장. '현재값 △증가량 증가율%' 형식이다.

    return s, trend_value, a3 # 완성된 이미지 링크, 매매동향 값, 코스피 일일값을 리턴값으로 지정

 

혹시 궁금하시거나 모르시는게 있다면 댓글 부탁드립니다.

아는 한도내에서 답변 드리겠습니다 ~ 

728x90
반응형