프로그램언어+/┗Crawling

1시간안에 금융주가 크롤링 (코딩10분, 포스팅 45분)

logthink 2018. 12. 30. 15:03

파이썬 크롤러 만들기

(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. 완료