본문 바로가기

파이썬으로 퀀트 프로그램 만들기 project

국내 주식 주가 데이터 크롤링

728x90

주가 정보를 수집할 수 있는 방법은 매우 많습니다.

그러나 퀀트 투자를 위한 백테스트나 종목선정을 위해서는 '수정주가'가 필요합니다.

수정주가란 액면분할 전 주가와 이후의 주가가 연속적으로 보이게 수정된 주가입니다.

수정주가 정보를 구할 수 있는 곳 중 하나로 '네이버 증권'을 이용하겠습니다.

 

[네이버 증권] -> [삼성전자 검색] -> [차트]에 들어가신 후,  개발자 도구 화면에서 네트워크를 키십니다. (링크)

그리고 차트에서 [일] 버튼을 클릭하면 주가 정보를 어떻게 얻는지를 개발자 도구 화면에서 알 수 있습니다.

 

 

여기서 맨 위에 'siseJson.naver? ~' 부분을 클리하시고 request url에서 수정주가 정보를 받아오는 것을 알 수 있습니다.

해당 url을 복사하여 브라우저 검색창에 입력해 보시면 수정주가 정보가 뜹니다.

 

 

그리고 url을 살펴보시면 'symbol'에는 티커, 'startTime'은 시작일, 'endTime'은 마지막 일 , 'timeframe'은 보여주는 시간 타입이라는 것을 알 수 있습니다.

이 정보를 이용해 파이썬을 통해서 주가 정보를 크롤링 해보겠습니다.

 

 

#파이썬 실습_1

우선 하나의 종목에 대한 주가 데이터만 크롤링 해보겠습니다.

먼저 이전 포스트에서 만들었던 주가 티커 데이터를 sql에서 불러오겠습니다.

## 주가 데이터 수집 전에 db에서 티커 데이터 불러오기 ##
from sqlalchemy import create_engine
import pandas as pd

engine = create_engine('mysql+pymysql://root:1234@127.0.0.1:3306/stock_db')
query = """
select * from kor_ticker
where 기준일 = (select max(기준일) from kor_ticker)
and 종목구분 = '보통주';
"""

ticker_list = pd.read_sql(query, con=engine)
engine.dispose()

 

이제 크롤링 해보겠습니다.

from dateutil.relativedelta import relativedelta # 날짜 
import requests as rq
from io import BytesIO
from datetime import date

i=0
ticker = ticker_list['종목코드'][i] #첫번째 종목 선택
fr = (date.today() + relativedelta(years = -5)).strftime("%Y%m%d")#5년전 부터
to = (date.today()).strftime("%Y%m%d")


url = f"""https://api.finance.naver.com/siseJson.naver?symbol={ticker}&requestType=1
&startTime={fr}&endTime={to}&timeframe=day"""

data = rq.get(url).content
data_price = pd.read_csv(BytesIO(data))

 

정규 표현식을 통한 클랜징을 하겠습니다.

#정규 표현식을 통한 클랜징
import re

#필요한 열만 선택
price = data_price.iloc[:, 0:6]

#columns 이름 변경
price.columns = ['날짜', '시가', '고가', '저가', '종가', '거래량']

#nan 값 날리기
price = price.dropna()

#날짜 데이터
price['날짜'] = price['날짜'].str.extract('(\d+)')
price['날짜'] = pd.to_datetime(price['날짜'])

#종목코드
price['종목코드'] = ticker

 

 

#파이썬 실습_2

이번에는 모든 국내 모든 종목에 대한 주가 정보를 크롤링해보겠습니다.

##### 모든 종목 주가 데이터 크롤링 #####
import pymysql
from sqlalchemy import create_engine
import pandas as pd
from datetime import date
from dateutil.relativedelta import relativedelta
import requests as rq
import time
from tqdm import tqdm
from io import BytesIO

#DB 연결
con = pymysql.connect(user='root',
                       passwd = '8019',
                       host = '127.0.0.1',
                       db = 'stock_db',
                       charset = 'utf8')

mycursor = con.cursor()

#티커리스트 불러오기
ticker_list = pd.read_sql("""
select * from kor_ticker
where 기준일 = (select max(기준일) from kor_ticker)
    and 종목구분 = '보통주';
""", con=engine)

# DB 저장 쿼리
query = """
    insert into kor_price (날짜, 시가, 고가, 저가, 종가, 거래량, 종목코드)
    values (%s,%s,%s,%s,%s,%s,%s) as new
    on duplicate key update
    시가 = new.시가, 고가 = new.고가, 저가 = new.저가,
    종가 = new.종가, 거래량 = new.거래량;
"""

#오류 발생시 저장할 리스트 생성
error_list = []

 

이제 반복문을 통해 모든 종목에 대해 크롤링 해보겠습니다. 

그런데 크롤링 도중 오류 발생을 염두해서 try except 구문을 통해 

오류 발생시 error_list에 해당 티커를 저장하겠습니다.

 

for i in tqdm(range(0, len(ticker_list))):

    #티커 선택
    ticker = ticker_list['종목코드'][i]

    #시작일과 종료일
    fr = (date.today() + relativedelta(years = -5)).strftime("%Y%m%d")#5년전 부터
    to = (date.today()).strftime("%Y%m%d")


    try:
        #url 생성
        url = f"""https://api.finance.naver.com/siseJson.naver?symbol={ticker}&requestType=1
        &startTime={fr}&endTime={to}&timeframe=day"""

        #데이터 다운로드
        data = rq.get(url).content
        data_price = pd.read_csv(BytesIO(data))

        #데이터 클렌징
        price = data_price.iloc[:, 0:6]
        price.columns = ['날짜', '시가', '고가', '저가', '종가', '거래량']
        price = price.dropna()
        price['날짜'] = price['날짜'].str.extract('(\d+)')
        price['날짜'] = pd.to_datetime(price['날짜'])
        price['종목코드'] = ticker

        #주가 데이터를 DB에 저장
        args = price.values.tolist()
        mycursor.executemany(query, args)
        con.commit()

    except:

        # 오류 발생시 error_list에 티커 저장하고 넘어가기
        print(ticker)
        error_list.append(ticker)

    #타임슬립 적용
    time.sleep(2)

약 1시간 30분 이상의 시간이 소요될 것입니다. 

모든 티커 주가 데이터가 저장이 완료되면 mysql에서 저장된 데이터를 확인하실 수 있을겁니다.