Python

주식투자 파이썬으로 해보자_금융데이터 수집하기#1

5시의그림자 2021. 12. 31. 23:08

"주식투자 파이썬으로 해보자" 첫 번째 글입니다.

(이 글은 이현열님의 'R을 이용한 퀀트 투자 포트폴리오 만들기'를 참고하여 작성하였습니다. 감사합니다)

 

요리하기 전에는 시장에 가서 재료를 사와야 하듯, 금융데이터를 분석하기 위해서는 재료인 데이터들을 구해야합니다.

파이썬으로 웹상에 있는 금융데이터를 수집하는 코드를 먼저 작성해서 기본 재료를 준비해보겠습니다.

 

#STEP 0, KRX 정보데이터시스템 탐색

데이터를 가져올 사이트는 KRX 정보데이터시스템(data.krx.co.kr)입니다.

 

KRX 정보데이터시스템

정보시스템의 [통계] > [기본통계] > [주식] > [세부안내] 중 아래 두 가지 데이터를 사용하려 합니다.

  • [12025] 업종분류 현황
  • [12021] PER/PBR/배당수익률(개별종목)

목표 데이터 사이트에는 다운로드 기능이 있어 excel, csv형태로 다운로드해서 사용 가능합니다. 

사이트 접속 후 데이터를 열고 다운로드 해도 되지만, 이런 단순반복은 컴퓨터에 맡기는 것이 효율적입니다.

그럼 데이터를 가져올 사이트를 파보도록 합시다.

 

"[12025] 업종분류 현황" 개발자 도구 화면

업종분류 현황 페이지 접속 후 F12(개발자 도구화면)을 열고 다운로드 버튼을 클릭한 후 "CSV"를 눌러줍니다.

개발자 도구의 Network 탭을 살펴보면 generate.cmd와 download.cmd 두 항목이 생성된 것을 확인할 수 있습니다.

프로세스를 뜯어보겠습니다.

  1. http://data.krx.co.kr/comm/fileDn/download_csv/download.cmd에 요청사항을 보냅니다.
  2. 요청사항에 해당하는 OTP(generate.cmd)를 받습니다.
  3. 부여받은 OTP를 사이트에 제출하면 데이터를 받을 수 있습니다.

요약하자면 원하는 메뉴를 보내고, 음식을 받는 과정과 유사하다고 보시면 되겠습니다.

그럼 프로세스를 코드로 만들어봅시다.

 

#STEP 1, OTP 코드 발급받기

# 코스피 업종분류 OTP 발급
import requests
from bs4 import BeautifulSoup

gen_otp_url = "http://data.krx.co.kr/comm/fileDn/GenerateOTP/generate.cmd"
gen_otp_data = {"mktId" : "STK",
                "trdDd" : "20211230",
                "money" : '1',
                "csvxls_isNo" : 'false',
                "name" : 'fileDown',
                "url" : 'dbms/MDC/STAT/standard/MDCSTAT03901'}

otp = requests.post(gen_otp_url, params = gen_otp_data)
otp = BeautifulSoup(otp.content, "html.parser").text

 

  1. gen_otp_url에 요청사항을 제출할 URL을 입력합니다.
  2. gen_otp_data에 요청사항을 dictionary 형태로 만들어줍니다.
  3. request.post를 통해 gen_otp_url에 gen_otp_data를 전송합니다.
  4. BeautifulSoup을 통해 HTML 내용을 text로 읽어줍니다.

이제 우리가 사용할 열쇠(OTP)를 받았으니 다운로드를 요청해볼까요?

 

#STEP 2, 코스피 업종분류 데이터 받아오기

# KRX 코스피 업종분류 데이터 다운로드
down_url = 'http://data.krx.co.kr/comm/fileDn/download_csv/download.cmd'
otp_key = {"code" : otp}
referer = {"referer" : gen_otp_url}
down_sector_KS = requests.post(down_url, data= otp_key, headers = referer).content.decode('EUC-KR')
down_sector_KS = io.StringIO(down_sector_KS)
down_sector_KS = pd.read_csv(down_sector_KS, sep = ',')

 

  1. down_url에 다운로드를 요청할 URL을 입력합니다.
  2. otp_key에 dictionary형태로 OTP값을 넣어줍니다.
  3. referer에 gen_otp_url을 넣어줍니다. referer란 각각의 웹사이트로 방문할 때 남는 흔적입니다. 서버가 로봇으로 인식하지 않도록 첫 번째 방문한 URL를 referer로 사용합니다.
  4. request.post를 통해 down_url로 OTP값을 제출합니다. 데이터는 EUC-KR로 인코딩 되어 있으니 decode('EUC-KR')를 통해 풀어줍니다.
  5. io.StringIO를 통해 문자열을 파일처럼 변경 후 pandas로 읽어줍니다.

코스피 업종분류 데이터가 잘 들어왔는지 확인해보겠습니다.

       종목코드      종목명   시장구분    업종명      종가   대비   등락률           시가총액
0    095570   AJ네트웍스  KOSPI   서비스업    5410  -50 -0.92   253308615950
1    006840    AK홀딩스  KOSPI   기타금융   19300 -100 -0.52   255677927300
2    027410      BGF  KOSPI   기타금융    5290  -20 -0.38   506341824390
3    282330   BGF리테일  KOSPI    유통업  145500 -500 -0.34  2514808323000
4    138930  BNK금융지주  KOSPI   기타금융    8400    0  0.00  2737856066400
..      ...      ...    ...    ...     ...  ...   ...            ...
938  069260      휴켐스  KOSPI     화학   23150 -200 -0.86   946339312200
939  000540     흥국화재  KOSPI     보험    3600   25  0.70   231273522000
940  000547  흥국화재2우B  KOSPI     보험   27700  250  0.91     4254720000
941  000545    흥국화재우  KOSPI     보험    8070   20  0.25     6197760000
942  003280     흥아해운  KOSPI  운수창고업    2700  -15 -0.55   649147227300

[943 rows x 8 columns]

 

코스피 총 943개 종목을 잘 가져왔군요.

 

#STEP 3, 코스닥 업종분류 데이터 받아오기

코스닥은 코스피 데이터 가져오는 것의 반복입니다.

gen_otp_data에 mktId만 'KSQ'로 수정해주고 나머지는 동일하게 진행합니다.

# KRX 코스닥 업종분류 OTP 발급
gen_otp_url = "http://data.krx.co.kr/comm/fileDn/GenerateOTP/generate.cmd"
gen_otp_data = {"mktId" : "KSQ", #바로 여기, 코스닥으로 변경
                "trdDd" : biz_day,
                "money" : '1',
                "csvxls_isNo" : 'false',
                "name" : 'fileDown',
                "url" : 'dbms/MDC/STAT/standard/MDCSTAT03901'}

otp = requests.post(gen_otp_url, params = gen_otp_data)
otp = BeautifulSoup(otp.content, "html.parser").text

# 코스닥 업종분류 데이터 다운로드
down_url = 'http://data.krx.co.kr/comm/fileDn/download_csv/download.cmd'
data = {"code" : otp}
headear = {"referer" : gen_otp_url}
down_sector_KQ = requests.post(down_url, data= data, headers = headear).content.decode('EUC-KR')
down_sector_KQ = io.StringIO(down_sector_KQ)
down_sector_KQ = pd.read_csv(down_sector_KQ, sep = ',')

 

코스닥 업종분류 데이터도 잘 들어왔는지 확인해보겠습니다.

        종목코드     종목명    시장구분     업종명     종가   대비   등락률          시가총액
0     060310      3S  KOSDAQ   기계·장비   3325   -5 -0.15  153852780725
1     054620  APS홀딩스  KOSDAQ      금융  14850 -450 -2.94  302854181850
2     265520   AP시스템  KOSDAQ     반도체  25200  100  0.40  385091809200
3     211270    AP위성  KOSDAQ    통신장비  14500   50  0.35  218693408000
4     032790    BNGT  KOSDAQ    정보기기   4075    0  0.00  120352455875
...      ...     ...     ...     ...    ...  ...   ...           ...
1531  024060    흥구석유  KOSDAQ      유통   7160  -70 -0.97  107400000000
1532  010240      흥국  KOSDAQ   기계·장비   7750  300  4.03   95500894000
1533  189980  흥국에프엔비  KOSDAQ  음식료·담배   3800   20  0.53  151991529800
1534  037440      희림  KOSDAQ   기타서비스   6860 -200 -2.83   95508178500
1535  238490      힘스  KOSDAQ     반도체   9850  -20 -0.20  111425524600

[1536 rows x 8 columns]

 

코스닥 총 943개 종목을 잘 가져왔군요.

 

#STEP 4, 코스피, 코스닥 데이터 합치기

이제 모아진 데이터를 하나로 합쳐보겠습니다.

# 코스피 & 코스닥 Concat
down_sector = pd.concat([down_sector_KS, down_sector_KQ])
down_sector.to_csv('data/krx_sector.csv',encoding='UTF-8', index = False)

 

  1. panda concat으로 코스피, 코스닥 데이터를 하나로 만들어줍니다.
  2. 잘 모아진 데이터를 앞으로 사용하기 위해 지정된 폴더 krx_sector.csv로 저장해줍니다. 파일명은 편한걸로 사용하면 됩니다.

 

다음 글에서는 [12021] PER/PBR/배당수익률(개별종목) 데이터를 가져오기로 이어가 보겠습니다.

 

감사합니다.