/ ALGORITHMIC-TRADING

KRX에서 종목코드 가져오기2

한국거래소(KRX)에서 증권과 관련된 데이터와 통계정보를 제공하는 정보데이터시스템 웹페이지가 있다.
여기서도 상장주식의 종목코드 리스트를 가져올 수 있다.

1. 홈페이지 둘러보기

KRX의 전자정보데이터시스템에 접속한다.

  • http://data.krx.co.kr/contents/MDC/MAIN/main/index.cmd

‘주식’-‘종목정보’-‘전종목 지정내역’ 또는 [다음] 링크를 클릭한다.

해당 화면에서 국내 상장주식의 기본정보를 조회할 수 있다. 우측에 다운로드 아이콘을 클릭하면 원하는 포맷으로 데이터를 다운로드 할수도 있다.

크롬에서 ‘F12’버튼 또는 마우스 우클릭 후 ‘검사’를 클릭하여 개발자 도구 창을 연다.
상단 탭에서 ‘Network’를 선택한다. 이 상태에서 앞에서 설명한 다운로드 항목에서 ‘CSV’ 아이콘을 클릭하여 파일 다운로드를 실행해본다. 개발자 도구창 하단에 ‘generate.cmd’, ‘download.cmd’가 새로 생성되었다.
즉, 파일 다운로드 과정은 두단계를 거치게 된다. ‘generate.cmd’에 의해서 데이터를 다운로드 하기 위한 code를 리턴한다. 이 후 ‘download.cmd’로 code를 파라미터로 하여 데이터를 저장한다.

‘generate.cmd’를 선택하고 상단의 ‘Headers’를 클릭해보자.
요청할 주소와 방식(POST) 등을 확인할 수 있다.
‘Payload’를 클릭하면 요청할 때 사용된 파라미터를 확인된다.

마찬가지로 ‘download.cmd’를 선택하고 상단의 ‘Headers’를 클릭해보자.
요청할 주소와 방식(POST)을 확인할 수 있다.
‘Payload’에는 code 값이 표시되어 있다. 이 값은 ‘generate.cmd’로 받아와야 하는 값이다.

이 정보를 바탕으로 코드를 작성한다.

2. 추출하기

웹에서 정보를 가져오기 위해 requests 라이브러리를 사용할 것이다.

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

import requests
import pandas as pd
from io import BytesIO

첫번째 단계로 generate 요청을 진행한다.
요청할 주소와 파라미터를 설정하자. 앞에 소개한 ‘generate.cmd’에 명시된 내용이다.

gen_url = 'http://data.krx.co.kr/comm/fileDn/GenerateOTP/generate.cmd'
gen_parms = {
    'mktId': 'ALL',
    'share': '1',
    'csvxls_isNo': 'false',
    'name': 'fileDown',
    'url': 'dbms/MDC/STAT/standard/MDCSTAT01901'
    }

python 코드에 의한 접근이 아닌 크롬으로 접근하고 있음을 표시하기 위해 header 정보를 추가한다.
‘Headers’ 하단에 있는 ‘Request Headers’ 항목을 참고하여 작성한다.

headers = {
    'Referer': 'http://data.krx.co.kr/contents/MDC/MDI/mdiLoader/index.cmd?menuId=MDC0201020101',
    'Upgrade-Insecure-Requests': '1',
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36' #generate.cmd에서 찾아서 입력하세요
    }

code 값을 리턴받기 위해 요청을 진행한다.

r = requests.get(url=gen_url, params=gen_parms, headers=headers)
r.content
b'a1n6kaOi+6ccSQWhSJQn6cmnCCnJIeb940e8ATaeiE4RtSksuLS7Bnxpl86F7dAOvXfGx9S2U5wgvoxsacATRRtmGtORI4WrGDmruVe6oXtCqUypoW0Lp6SAPP0PhVkgThCTcjIZNPI5lCTubZnhjio6AHXdxc45YVEhz4JdugHPMxvIwHadpQpCGE1HxZAXvTCprTIXuXT9XxFb88awpQ=='

r.content에 code 값이 저장되었다.

이제 두번째 단계, 다운로드 요청을 진행한다. ‘download.cmd’에 표시된 요청주소를 참고하고, code는 앞에서 받은 값을 지정한다.

down_url = 'http://data.krx.co.kr/comm/fileDn/download_csv/download.cmd'
data = {
    'code': r.content
}
r = requests.post(url=down_url, data=data, headers=headers)
r.content

이렇게 받은 정보는 바이너리 데이터이다.
이 데이터를 다루기 위해 BytesIO 메서드를 사용한다.
이제 pandas의 read_csv 메서드로 데이터를 읽어온다.

stock_code = pd.read_csv(BytesIO(r.content), encoding='cp949')
stock_code.head()

필요한 컬럼만 가져오고 컬럼명을 영문으로 변경한다.

stock_code = stock_code[['한글 종목약명', '단축코드', '시장구분', '액면가', '상장주식수']]
stock_code = stock_code.rename(columns = {'시장구분': 'market', '한글 종목약명': 'name', '단축코드': 'code', 
                                          '액면가': 'par_value', '상장주식수': 'total_shrs'})
stock_code.head()
name code market par_value total_shrs
0 마이크로컨텍솔 098120 KOSDAQ 500 8312766
1 스카이이앤엠 131100 KOSDAQ 500 11642629
2 포스코엠텍 009520 KOSDAQ 500 41642703
3 AJ네트웍스 095570 KOSPI 1000 46822295
4 AK홀딩스 006840 KOSPI 5000 13247561

3. 함수로 정리하기

def get_krx_code():
    gen_url = 'http://data.krx.co.kr/comm/fileDn/GenerateOTP/generate.cmd'
    gen_parms = {
        'mktId': 'ALL',
        'share': '1',
        'csvxls_isNo': 'false',
        'name': 'fileDown',
        'url': 'dbms/MDC/STAT/standard/MDCSTAT01901'
        }
    headers = {
    'Referer': 'http://data.krx.co.kr/contents/MDC/MDI/mdiLoader/index.cmd?menuId=MDC0201020101',
    'Upgrade-Insecure-Requests': '1',
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36' #generate.cmd에서 찾아서 입력하세요
    }
    r = requests.get(url=gen_url, params=gen_parms, headers=headers)
    
    down_url = 'http://data.krx.co.kr/comm/fileDn/download_csv/download.cmd'
    data = {
        'code': r.content
    }
    r = requests.post(url=down_url, data=data, headers=headers)
    
    stock_code = pd.read_csv(BytesIO(r.content), encoding='cp949')
    stock_code = stock_code[['한글 종목약명', '단축코드', '시장구분', '액면가', '상장주식수']]
    stock_code = stock_code.rename(columns = {'시장구분': 'market', '한글 종목약명': 'name', '단축코드': 'code', 
                                              '액면가': 'par_value', '상장주식수': 'total_shrs'})
    
    return stock_code