파이썬 크롤러 만들기
(Naver 금융 주식 데이터 수집하기)
>> list
○ 특정 종목의 가격 받아오기
○ 여러 종목의 가격 받아오기
○ 특정 종목의 봉차트 데이터(open, close, high, low)받아오기
○ 여러 종목의 봉차트 데이터(시고저종) 받아오기
[사진1] 네이버 금융
[!] HTML 데이터 수집하기
1 2 3 4 5 6 7 8 9 10 11 | # -*-coding: utf-8 -*- import requests from bs4 import BeautifulSoup def get_bs_obj(): url = "https://finance.naver.com/item/main.nhn?code=035420" result = requests.get(url) bs_obj = BeautifulSoup(result.content, "html.parser") return print(bs_obj) print(get_bs_obj()) | cs |
[@] Price 데이터 수집하기
개발자 도구에서 엘리먼트 영역 확인. (<p class="no_today"></p>)
1 2 3 4 5 6 | #가공된 requests의 content bs_obj = get_bs_obj() #총액 element가져오기(단일) no_today = bs_obj.find("p", {"class":"no_today"}) blind_now = no_today.find("span", {"class":"blind"}) print(blind_now.text) | cs |
회사별 코드 수집 후 URL에 삽입하는 메서드 선언
naver code = 035420
삼성 code = 005930
현대 code = 000720
sk 하이닉스 code = 000660
코오롱 code = 144620
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | # -*-coding: utf-8 -*- import requests from bs4 import BeautifulSoup def get_bs_obj(company_code): url = "https://finance.naver.com/item/main.nhn?code={}".format(company_code) result = requests.get(url) bs_obj = BeautifulSoup(result.content, "html.parser") return bs_obj def get_price(company_code): bs_obj = get_bs_obj(company_code) no_today = bs_obj.find("p", {"class":"no_today"}) blind_now = no_today.find("span", {"class":"blind"})#총액 element가져오기(단일) return blind_now.text company_codes = ['035420', '005930', '000720', '000660', '144620'] for item in company_codes: price = get_price(item) print(price) | cs |
그리고 결과
그림[2] 시가 확인
workflow 확인해보면 (1) GET요청 (2) html byte 수집 (3) html parser (4) 총액 엘리먼트 access (5) get text (6) 각 company code 요청
그림[3]
이제는 특정 종목의 봉차트 데이터(open, close, high, low)받아오기를 해보자.
1 2 3 4 5 6 7 8 9 10 | def get_candle_chart_data(company_code): bs_obj = get_bs_obj(company_code) td_first = bs_obj.find("td", {"class":"first"}) blind = td_first.find("span", {"class":"blind"}) #close 종가(전일) close = blind.text return close candle_chart_data = get_candle_chart_data("000660") print(candle_chart_data) | cs ㅇㅇ |
일단은 전일을 구하였다. 그리고 고가를 구해야하는데, element상 전혀 다른 접근을 해야된다.
그림[4]
<td>라는 태그가 class안에 any로 접근해야해서 find( ) 메서드로는 구할 수 가 없어 findAll( )을 사용해야한다.
이는 find( ) 데이터를 list( ) 하여 return 해준다. (따라서 슬라이스로 접근가능)
그래서 반복해서 table -> tr -> td [0] td [1] td [2].....이렇게 접근
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | def get_candle_chart_data(company_code): bs_obj = get_bs_obj(company_code) td_first = bs_obj.find("td", {"class":"first"}) blind = td_first.find("span", {"class":"blind"}) #close 종가(전일) close = blind.text #high 고가 table = bs_obj.find("table", {"class":"no_info"}) trs = table.findAll("tr") #tr묵인 block확인 first_tr = trs[0] #전일하고 고가 확인 first_tr_tds = first_tr.findAll("td") #.findAll() => [, ,] first_tr_tds_second_td = first_tr_tds[1] #<td>의 고가 확인 high = first_tr_tds_second_td.find("span", {"class":"blind"}).text return {"close":close, "high":high} candle_chart_data = get_candle_chart_data("000660") print(candle_chart_data) | cs |
쭉 이어서 시고저종 모두 구했다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | def get_candle_chart_data(company_code): bs_obj = get_bs_obj(company_code) td_first = bs_obj.find("td", {"class":"first"}) blind = td_first.find("span", {"class":"blind"}) #close 종가(전일) close = blind.text #high 고가 table = bs_obj.find("table", {"class":"no_info"}) trs = table.findAll("tr") #tr묵인 block확인 first_tr = trs[0] #전일하고 고가 확인 first_tr_tds = first_tr.findAll("td") #.findAll() => [, ,] first_tr_tds_second_td = first_tr_tds[1] #<td>의 고가 확인 high = first_tr_tds_second_td.find("span", {"class":"blind"}).text #open 시가 second_tr = trs[1] second_tr_td_first = second_tr.find("td", {"class", "first"}) blind_open = second_tr_td_first.find("span", {"class":"blind"}) open = blind_open.text #low 저가 second_tr_tds = second_tr.findAll("td") #list [, ,] second_tr_sec_td = second_tr_tds[1] blind_low = second_tr_sec_td.find("span", {"class":"blind"}) low = blind_low.text return {"close":close, "high":high, "open":open, "low":low} company_codes = ['035420', '005930', '000720', '000660', '144620'] for item in company_codes: candle_chart_data = get_candle_chart_data(item) print(candle_chart_data) | cs |
get property를 모듈화 하면 더 수월하다. 그리고 ouput.
1 2 3 4 5 6 | PS C:\Users\namki\Desktop\naver잠식> python .\naver_stock_crwal.py {'close': '122,500', 'high': '123,000', 'open': '122,500', 'low': '120,500'} {'close': '38,250', 'high': '38,900', 'open': '38,250', 'low': '38,200'} {'close': '53,700', 'high': '55,900', 'open': '53,300', 'low': '53,300'} {'close': '61,600', 'high': '62,300', 'open': '61,700', 'low': '60,500'} {'close': '2,885', 'high': '3,000', 'open': '2,900', 'low': '2,830'} | cs |
이로써 끝났다.
# 프로젝트 금융에서 종목별로 종목이름, 가격수집
# 1. 프로젝트 만들기
# 2. 디렉터리 생성(package)
# 3. .py 생성
# 4. get( ) 만들기
# 5. 함수 return format
# 6. naver finance의 특정 종목 url 복사
# 7.requests 받기->get메서드
# 8. bs4 파싱
# 9. html data 객체 생성
# 10. F12로 엘리먼트 획득
# 11. 출력하고, 정상 데이터를 리턴
# 12. 반복문
# 13. 회사 코드 만들기
# 14. 함수 연결
# 15. 파라미터 수정(하드코딩)
# 16. 예외처리
# 17. 완료
'프로그램언어+ > ┗Crawling' 카테고리의 다른 글
크롤링(html, ajax, javascript)문제 (0) | 2018.12.31 |
---|---|
크롤러 만들때 robots.txt 주의 (0) | 2018.12.31 |
이 글을 읽기만 해도 가능한 크롤링(작업중) (0) | 2018.12.28 |
페이스북 페이지 크롤링 (0) | 2018.12.26 |