ai-creator

[Python] 금융 - 주식 데이터 가져오기 & 차트 그리기 본문

오늘 배워 오늘 쓰는 OpenAPI/Quick Start

[Python] 금융 - 주식 데이터 가져오기 & 차트 그리기

ai-creator 2020. 6. 13. 07:02
반응형

<< 목표 >>

네이버 금융에서 원하는 종목의 일별 시세를 크롤링해보고, 2가지 종류의 그래프를 그려봅니다.

<< 사전 준비 >>

- 라이브러리

$ pip install pandas
$ pip install matplotlib
$ pip install plotly 

<< 구현 순서 >>

Step 1 URL 구조 확인
Step 2 한국 거래소 종목 가져오기
Step 3 주식 데이터 가져오기
Step 4 차트 그리기

Step 1) URL 구조 확인

먼저 크롤링할 네이버 금융의 url 구조를 확인해보자.

LG화학의 경우를 살펴보면, 다음과 같다.

 

https://finance.naver.com/ > "LG화학" 검색 > [시세] 탭 클릭

 

여기에 적힌 051910이라는 값이  "종목코드"를 의미합니다.

즉, 코스피(KOSPI)와 코스닥(KOSDAQ)의 종목 코드 목록을 알면 쉽게 데이터를 가지고 올 수 있다는 의미입니다.

 

Step 2) 한국 거래소 종목 가져오기

코스피(KOSPI)와 코스닥(KOSDAQ)의 종목 코드 목록은 어디에 있을까요?

3000여 개나 되는 코드를 하나하나 찾는 건 귀찮은 일이니, 한국 거래소 (KRX)를 통해 가져오면 된됩니다.

한국 거래소에서는 상장법인목록을 엑셀 파일로 다운로드할 수 있게 제공이 되기 때문에 사용하기 편합니다!!

 

import pandas as pd 

#해당 링크는 한국거래소에서 상장법인목록을 엑셀로 다운로드하는 링크입니다.
#다운로드와 동시에 Pandas에 excel 파일이 load가 되는 구조입니다.
stock_code = pd.read_html('http://kind.krx.co.kr/corpgeneral/corpList.do?method=download', header=0)[0] 
#stock_code.head()

# 데이터에서 정렬이 따로 필요하지는 않지만 테스트겸 Pandas sort_values를 이용하여 정렬을 시도해봅니다.
stock_code.sort_values(['상장일'], ascending=True)

# 필요한 것은 "회사명"과 "종목코드" 이므로 필요없는 column들은 제외
stock_code = stock_code[['회사명', '종목코드']] 

# 한글 컬럼명을 영어로 변경 
stock_code = stock_code.rename(columns={'회사명': 'company', '종목코드': 'code'}) 
#stock_code.head()

# 종목코드가 6자리이기 때문에 6자리를 맞춰주기 위해 설정해줌 
stock_code.code = stock_code.code.map('{:06d}'.format) 

Step 3) 주식 데이터 가져오기

step2 에서 가져온 종목 코드와 함께 일별 시세를 가지고 옵니다.

- 종목 검색 : https://finance.naver.com/item/sise_day.nhn?code=[종목코드]

- 일별 시세 구조 : https://finance.naver.com/item/sise_day.nhn?code=[종목코드]&page=[페이지번호]

 

step3-1) LG화학에 대해서 page=1 인 경우만 가져오기

- www.useragentstring.com에서 User-Agent를 확인 합니다.

import requests

# LG화학의 일별 시세 url 가져오기 
company='LG화학' 
code = stock_code[stock_code.company==company].code.values[0].strip() ## strip() : 공백제거
page = 1

url = 'http://finance.naver.com/item/sise_day.nhn?code={code}'.format(code=code)     
url = '{url}&page={page}'.format(url=url, page=page)
print(url)
header = {'User-Agent':'<복사한 user-agent 값 대체>'}  
res = requests.get(url,headers=header)
df = pd.read_html(res.text, header=0)[0]
df.head()

 

step3-2) LG화학에 대해서 page를 반복해서 대량의 데이터 가져오기

company='LG화학' 
code = stock_code[stock_code.company==company].code.values[0].strip() ## strip() : 공백제거

df = pd.DataFrame()
for page in range(1,21):
    url = 'http://finance.naver.com/item/sise_day.nhn?code={code}'.format(code=code)     
    url = '{url}&page={page}'.format(url=url, page=page)
    print(url)
    df = df.append(pd.read_html(url, header=0)[0], ignore_index=True)

 

step3-3) 데이터 클린징

# df.dropna()를 이용해 결측값 있는 행 제거 
df = df.dropna() 

# 한글로 된 컬럼명을 영어로 바꿔줌 
df = df.rename(columns= {'날짜': 'date', '종가': 'close', '전일비': 'diff', '시가': 'open', '고가': 'high', '저가': 'low', '거래량': 'volume'}) 
# 데이터의 타입을 int형으로 바꿔줌 
df[['close', 'diff', 'open', 'high', 'low', 'volume']] = df[['close', 'diff', 'open', 'high', 'low', 'volume']].astype(int) 

# 컬럼명 'date'의 타입을 date로 바꿔줌 
df['date'] = pd.to_datetime(df['date']) 

# 일자(date)를 기준으로 오름차순 정렬 
df = df.sort_values(by=['date'], ascending=True) 

# 상위 5개 데이터 확인 
df.head()

Step 4) 차트 그리기

필요한 라이브러리를 import 합니다.

단순형 차트는 seaborn 라이브러리를

반응형 차트는 plotly 라이브러리를 사용하겠습니다.

import matplotlib.pyplot as plt
# 필요한 모듈 import 하기 
import plotly
import plotly.graph_objects as go
import plotly.express as px

# %matplotlib inline 은 jupyter notebook 사용자용 - jupyter notebook 내에 그래프가 그려지게 한다.
%matplotlib inline 

Step 4-1) 단순형 차트 그리기

plt.figure(figsize=(10,4))
plt.plot(df['date'], df['close'])
plt.xlabel('')
plt.ylabel('close')
plt.tick_params(
    axis='x',          # changes apply to the x-axis
    which='both',      # both major and minor ticks are affected
    bottom=False,      # ticks along the bottom edge are off
    top=False,         # ticks along the top edge are off
    labelbottom=False) # labels along the bottom edge are off
plt.savefig(company + ".png")
plt.show()

Step 4-2) 반응형 차트 그리기

Plotly라이브러리 (https://plotly.com/python/)를 이용해 Time Series 그래프 그리기를 그려봅시다.

fig = px.line(df, x='date', y='close', title='{}의 종가(close) Time Series'.format(company))

fig.update_xaxes(
    rangeslider_visible=True,
    rangeselector=dict(
        buttons=list([
            dict(count=1, label="1m", step="month", stepmode="backward"),
            dict(count=3, label="3m", step="month", stepmode="backward"),
            dict(count=6, label="6m", step="month", stepmode="backward"),
            dict(step="all")
        ])
    )
)
fig.show()

(참고) html 코드로 저장하기

fig.write_html("file.html")

짜잔~~ 버튼도 있고, 스크롤바 처럼 생긴 부분들을 움직일 수 있는 반응형 그래프가 만들어졌어요~~~

더 많은 종목을 크롤링해서 사용한다면 어떻게 해야 할까요? 어디에 for문을 넣어야 하는지 고민해보세요^^

 

이렇게 크롤링한 데이터를 나만의 DB를 만들어서 관리해서 좋고,

만들어진 차트를 나만의 웹서버를 만들어서 봐도 좋고요,

차트들을 이미지로 다운로드 받아서 ppt를 만들어서 분석자료를 메일로 받아봐도 좋을 것 같아요.

 

또, 요즘에는 주식 뉴스를 작성하는 봇들이 있는거 아시죠? 이 내용을 배우고 나면, 어렵지 않게 할 수 있답니다~

(참고) 뉴스 봇

> WOW TV (Link)

> FNNEWS (Link)

 

여러분들도 다양하게 활용해보세요~ 

<< 참고 >>

- excelsior-cjh.tistory.com/109

 

 

 

 

반응형
Comments