앞선 포스팅에 계속하여 슬랙 알림봇이 매일매일 증시정보를 가져와서 알려주게끔 웹스크래이핑 기능을 더해보겠습니다. 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) 를 하셔도 됩니다. 그렇지만 개발자도구를 써서보면 해당 소스코드가 홈페이지 어디에 위치하는지 시각적으로 보여주므로 찾기 쉬우니 개발자도구를 활용하시는 걸 추천드립니다.)
원하는 요소들은 각각 아래의 위치에 있습니다.
그래프 이미지 주소 : 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 # 완성된 이미지 링크, 매매동향 값, 코스피 일일값을 리턴값으로 지정
혹시 궁금하시거나 모르시는게 있다면 댓글 부탁드립니다.
아는 한도내에서 답변 드리겠습니다 ~
'프로젝트 > [ed]_슬랙봇_증시알림' 카테고리의 다른 글
[Python] 슬랙(Slack) 알림봇 설정하여 매일 증시 알림 받기 (5) (0) | 2021.10.12 |
---|---|
[Python] 슬랙(Slack) 알림봇 설정하여 매일 증시 알림 받기 (4) (0) | 2021.10.02 |
[Python] 슬랙(Slack) 알림봇 설정하여 매일 증시 알림 받기 (3) - 2 (3) | 2021.09.25 |
[Python] 슬랙(Slack) 알림봇 설정하여 매일 증시 알림 받기 (2) (0) | 2021.09.22 |
[Python] 슬랙(Slack) 알림봇 설정하여 매일 증시 알림 받기 (1) (0) | 2021.09.22 |