금융 데이터 수집

2020. 7. 12. 22:42금융 데이터 분석

반응형

금융 분석을 하기 위해서 주가 데이터를 가져오는 방안에 대해서 정리해보려고 합니다.

주가 데이터를 가져오는 방안으로는 크게 3가지가 있는 것 같습니다. 1) 수동으로 주가 데이터를 다운로드 받는 방법 2) 증권사 API를 통해 수집하는 방법 3) 웹 크롤링(네이버 금융)을 통해 수집하는 방법입니다. 

저의 경우에는 키움증권 API를 통해 데이터를 수집하기도 하지만 효율이 떨어지는 것 같습니다. 단순히 분석을 위해서는 주로 1)수동 다운로드 2) 웹 크롤링을 주로 활용하고 있습니다. 따라서 이 두가지 방안에 대해서 간략히 정리하도록 하겠습니다.

먼저 수동으로 다운로드 받는 경우입니다.

저의 경우에는 이 때는 Yahoo Finance(https://finance.yahoo.com/)를 자주 활용하는데요, Yahoo Finance에 들어가서 원하는 회사의 종목을 검색하여 Historical Data를 다운로드를 받습니다. 예를 들어 Yahoo Finance에서 Samsung Electronics를 검색한 후 Historical Data를 조회하여 다운로드를 받습니다.

이와 같이 원하는 종목을 검색하여 Historical Data 탭에 들어가 원하는 조건을 적용(Apply)한 후 다운로드를 받으시면 됩니다.

그다음은 웹 크롤링을 하는 방법입니다. 저는 주로 네이버 금융정보를 활용합니다. 제가 네이버 금융 정보 크롤링을 하기 위해서 아래의 두 블로그를 주로 참조하였습니다.

http://blog.quantylab.com/crawling_naverfin_daycandle.html

https://acta.tistory.com/26

아래는 제가 위 두 블로그를 참조하여 만든 크롤링을 위한 코드 입니다.

먼저 필요한 모듈들을 Import 합니다.

1
2
3
4
import pandas as pd
import requests # Http 요청을 위한 모듈
from bs4 import BeautifulSoup # HTML, XML에서 데이터를 추출하기 위한 모듈
import datetime # 시간 데이터를 다루기 위한 모듈
cs

여기서는 하나의 회사 "삼성전자" 주가만을 가져오도록 구성하도록 하겠습니다. 여기서 정리된 내용을 기반으로 자신만의 Class나 함수를 만들어 코드만 입력하면 원하는 데이터를 가져오는 크롤러를 구성하실 수 있을 것입니다.

먼저 requests 모듈을 이용하여 특정 url의 정보를 요청하고, BeautifulSoup을 이용하여 해당 url의 html정보를 읽어 옵니다.

1
2
3
4
5
6
#삼성전자 code = 005930
url = 'https://finance.naver.com/item/sise_day.nhn?code={code}'.format(code="005930")
res = requests.get(url)
soap = BeautifulSoup(res.text, "lxml")
print(url) ## https://finance.naver.com/item/sise_day.nhn?code=005930 
 
cs

그 다음 표가 몇 페이지까지 구성되어 있는지를 확인 합니다. 해당 사이트로 가서 페이지 네비게이션에 마우스를 올린후 오른쪽 클릭 후 검사를 누르시면 해당 페이지 네비게이션의 html 내용을 확인 할 수 있습니다. 해당 사이트의 경우 "Nnavi"클래스의 테이블에 저장되어 있으며, 마지막 페이지 숫자는 "pgRR"클래스의 이름을 가진 td 태그에 저장되어 있습니다.

1
2
3
4
5
6
7
## 몇 Page 까지 있는지 조회
table_navi = soap.find("table", class_ ="Nnavi"## table중에서 Class가 "Nnavi"인 것을 탐색
td_navi = table_navi.find("td", class_="pgRR"## Class가 "Nnavi"인 Table 중에서 Class가 "pgRR"인 td 태그를 탐색
page_last = td_navi.a.get("href"## 탐색한 td 중에서 a태그를 탐색하여 그중에서 "href" 내용을 가지고 옴 
print(page_last) ##  /item/sise_day.nhn?code=005930&page=605
page_last = int(page_last.split("&")[1].split("=")[1]) # 605만 추출하여 정수로 저장
print(page_last) ## 605
cs

위의 코드를 실행하면 최종적으로 마지막 페이지 숫자를 나타내는 605라는 결과가 반환됩니다.

그 다음으로는 주가 테이블에서 주가 정보를 수집합니다. Pandas에서 정말 편리하게 Html에서 테이블 정보를 가지고 올 수 있는 read_html 함수를 제공해주고 있습니다. 각 페이지 별로 테이블 정보를 읽어 저장합니다.

1
2
3
4
5
6
7
8
9
10
## 시세 정보 수집
for i in range(page_last):
    print(i)
    base_url = requests.get('https://finance.naver.com/item/sise_day.nhn?code={}&page={}'.format("005930",i+1))
    table = pd.read_html(base_url.text) ## 요청한 url 중 table 정보를 읽어옴
        
    if i+1 == 0:
        data = table[0## 읽은 table중에서 첫번째 있는 테이블이 주가 테이블임
    elif i+1 >= 1:
        data = pd.concat([data, table[0]])
cs

이제 가지고 온 데이터 중에서 NA(빈 값) 데이터를 제거해 줍니다. 주말이나 공휴일에는 주식 시장이 열리지 않기 때문에 NA값으로 나타납니다. 최종적으로 원하는 날짜 기간을 설정하여 데이터를 조회합니다.

1
2
3
data=data.dropna()
start_datefrom = datetime.datetime.strftime(datetime.datetime(year=2018, month=7, day=12), '%Y.%m.%d')
data=data.loc[data["날짜"]>start_datefrom]
cs

마지막으로 데이터를 확인해 보겠습니다.

1
data.head(10)
cs
  날짜 종가 전일비 시가 고가 저가 거래량
0 2020.07.10 52700.0 100.0 53100.0 53200.0 52300.0 13646439.0
1 2020.07.09 52800.0 200.0 53200.0 53600.0 52800.0 17054850.0
2 2020.07.08 53000.0 400.0 53600.0 53900.0 52900.0 19664652.0
3 2020.07.07 53400.0 1600.0 55800.0 55900.0 53400.0 30760032.0
4 2020.07.06 55000.0 1400.0 54000.0 55000.0 53800.0 19856623.0
5 2020.07.03 53600.0 700.0 53000.0 53600.0 52700.0 11887868.0
6 2020.07.02 52900.0 300.0 52100.0 52900.0 52100.0 14142583.0
7 2020.07.01 52600.0 200.0 53400.0 53600.0 52400.0 16706143.0
8 2020.06.30 52800.0 400.0 53900.0 53900.0 52800.0 21157172.0
9 2020.06.29 52400.0 900.0 52500.0 53200.0 52000.0 17776925.0

 

반응형