ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [코딩_03] KRX 정보데이터시스템에서 전종목 기본정보 가져오기 (KRX 크롤링)
    개발일지 2022. 10. 1. 18:19
    반응형

     

    안녕하세요.

     

    비주얼 스튜디오 코드 설치와 확장 프로그램 설치까지 끝났다면, 이제는 본격적으로 코딩을 해보아야겠죠?

     

    오늘은 'KRX 정보데이터시스템'에서 전종목 기본정보를 크롤링해보려 합니다!

     

    전종목 기본정보는 '표준코드, 종목코드, 종목명' 등의 정보를 말합니다.

     

    해당 정보를 기반으로 나중에 종목명을 입력하면 주가 정보를 자동으로 크롤링하는 것이 목표입니다.

     

    그러면 바로 시작하겠습니다!

    0. 전체 코드 보기

    전체 코드 내용만 궁금하신 분은 더보기를 눌러서 확인해주세요!

    더보기
    import requests
    import pandas as pd
    from io import BytesIO
    import openpyxl
    from openpyxl.utils.dataframe import dataframe_to_rows
    
    def mk_all_stock_info():
        """
        KRX에서 제공하는 전종목 기본정보 중 '표준코드', '종목코드', '한글 종목약명'을 데이터프레임에 저장
    
        Returns:
            DataFrame: 한글종목약명(index), 표준코드, 종목코드
        """
        
        # generate.cmd > Headers > General > Request URL 주소
        gen_otp_url = 'http://data.krx.co.kr/comm/fileDn/GenerateOTP/generate.cmd'
    
        # generate.cmd > Payload > Form Data 내용
        gen_otp_data = {
            'locale': 'ko_KR',
            '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'}
        otp = requests.post(gen_otp_url, gen_otp_data, headers=headers).text
    
        # download.cmd > Headers > General > Request URL 주소
        down_url = 'http://data.krx.co.kr/comm/fileDn/download_csv/download.cmd'
    
        # requests로 data 전달
        down_stock_info = requests.post(down_url, {'code':otp}, headers=headers)
        
        # pandas를 이용해 Dataframe으로 다운받은 csv 저장
        stock_info = pd.read_csv(BytesIO(down_stock_info.content), encoding='EUC-KR')
        
        # DataFrame return
        return stock_info
    
    stock_info = mk_all_stock_info()
    
    stock_info
    
    # 엑셀 파일 저장 경로 설정 *** 미리 엑셀 파일은 만들어야 합니다 ***
    save_path = r"원하는 경로 설정\stock_info.xlsx"
    
    # 엑셀 오픈
    wb = openpyxl.load_workbook(save_path)
    
    # 엑셀 시트 지정
    ws = wb['Sheet1']
    
    # 데이터프레임 'stock_info'를 한줄씩 엑셀에 작성
    for r in dataframe_to_rows(stock_info, index=False, header=True):
        ws.append(r)
    
    # 엑셀 저장
    wb.save(save_path)

     

    1. KRX 정보데이터시스템 접속하기

    KRX, 한국거래소에서는 지수, 종목에 대해서 기간별 추이, 투자자별 매매 동향 등에 대한 정보를 제공합니다.해당 데이터들은 주요하게 사용될 수 있으니 알아두시면 좋은 사이트입니다.

     

    검색 페이지에서 'krx 정보데이터시스템' 검색 혹은 하단의 링크를 통해 페이지에 접속을 해봅니다.

     

    KRX 정보데이터시스템: http://data.krx.co.kr/contents/MDC/MAIN/main/index.cmd

     

    KRX 정보데이터시스템

    증권·파생상품의 시장정보(Marketdata), 공매도정보, 투자분석정보(SMILE) 등 한국거래소의 정보데이터를 통합하여 제공 서비스

    data.krx.co.kr

     

    페이지에 접속을 성공적으로 하셨다면, 이번에 크롤링을 할 전종목 기본정보를 확인해보러 갑시다!

    페이지 좌측 내비게이션 바: '메인페이지 > 종목정보 > 전종목 기본정보'

    KRX 정보데이터시스템 메인페이지

     

    2. 홈페이지에서 전종목 기본정보 다운로드 받기

    전종목 기본정보 페이지에 들어가면 아래의 이미지처럼 보입니다.

    F12 버튼을 눌러서 개발자 도구를 엽니다.

    개발자 도구가 켜지면 보통 Element로 되어있는데, Network를 눌러줍니다.
    (이해가 잘 가지 않을 수 있지만 하단의 이미지를 참고해주시면 감사하겠습니다.)

    전종목 기본정보 확인 페이지 접속 및 개발자 도구 열기

     

    하단의 이미지를 참고해 전종목 기본정보를 CSV로 다운받아봅니다.

    (다운로드 팝업을 클릭 > CSV클릭)

    그러면 개발자 도구에 갑작스럽게 'generate.cmd', 'download.cmd'라는 파일이 생깁니다.

    이제 저 generate.cmd와 download.cmd를 이용해 페이지에 접속하지 않고도 전종목 기본정보를 다운받을 것입니다.

    전종목 기본정보 CSV로 다운받기

     

    3. 라이브러리 임포트

     

    크롤링을 하기 위한 라이브러리들을 Import 해줍니다.

    각각의 라이브러리들은 다음과 같은 역할을 수행합니다.

    (저는 전공자가 아니며 해당 내용이 정확하진 않습니다. 제가 해당 코드에서 라이브러리를 사용하는 목적에 대해서 간단하게 적은 것입니다.)

    • requests: 크롤링을 위한 라이브러리
    • pandas: 데이터 형식을 손쉽게 다루기 위한 라이브러리
    • openpyxl: 파이썬으로 엑셀을 다루기 위한 라이브러리
    import requests
    import pandas as pd
    from io import BytesIO
    import openpyxl
    from openpyxl.utils.dataframe import dataframe_to_rows​

     

    4. 크롤링 함수 만들기

     

    4-1. 함수 선언하기

    우선 함수를 한번 선언해봅니다.함수명은 정해진 것은 없으니 원하시는 이름으로 만드시면 됩니다.저는 모든 종목의 정보를 만든다는 이름으로 지어보았습니다.

    def mk_all_stock_info():
        """
        KRX에서 제공하는 전종목 기본정보 중 '표준코드', '종목코드', '한글 종목약명'을 데이터프레임에 저장
    
        Returns:
            DataFrame: 한글종목약명(index), 표준코드, 종목코드
        """

     

    4-2. generate.cmd 정보 가져오기

    이제 크롤링을 하기 위해 generate.cmd에 있던 정보를 이용합니다.

    1. generate.cmd > Headers > General을 들어가 Request URL이라는 것을 복사해줍니다.
    (해당 url을 통해 정보를 불러올 예정입니다.)

    2. 비주얼 스튜디오 코드에 변수로 저장을 해줍니다.

    generate.cmd >  Headers > General > Request URL 복사

    # generate.cmd > Headers > General > Request URL 주소
    gen_otp_url = 'http://data.krx.co.kr/comm/fileDn/GenerateOTP/generate.cmd'

     

    3. generate.cmd > Payload를 들어가면 Form Data가 있는데, Request URL 복사하듯 복사를 해줍니다.

    4. 비주얼 스튜디오 코드에 변수로 저장을 해줍니다.

    generate.cmd >  Payload > Form Data 복사

    # generate.cmd > Payload > Form Data 내용
    gen_otp_data = {
        'locale': 'ko_KR',
        'mktId': 'ALL',
        'share': '1',
        'csvxls_isNo': 'false',
        'name': 'fileDown',
        'url': 'dbms/MDC/STAT/standard/MDCSTAT01901'
    }

     

    5. 로봇으로 인식하지 않도록 header를 설정한 이후, requests 라이브러리를 이용해 정보를 받아옵니다.
    requests의 방식은 post와 get이 있는데 post 방식을 사용하셔야 합니다.

    (generate.cmd > Headers > General > Request Method 참고)

    requests.post(크롤링하고싶은 url, 크롤링을 위해 넘겨주는 데이터 정보) 형태로 코드를 작성해주시면 됩니다.

    # 로봇으로 인식하지 않게 하기 위함
    headers = {'Referer' : 'http://data.krx.co.kr/contents/MDC/MDI/mdiLoader'}
    otp = requests.post(gen_otp_url, params=gen_otp_data, headers=headers).text

     

    4-3. download.cmd 정보 가져오기

    이번에는 download.cmd에 있는 정보를 불러올 것입니다.

    1. download.cmd > Headers > General을 들어가 Request URL이라는 것을 복사해줍니다.
    (해당 url을 통해 정보를 불러올 예정입니다.)

    2. 비주얼 스튜디오 코드에 변수로 저장을 해줍니다.

    download.cmd >  Headers > General > Request URL 복사

    # download.cmd > Headers > General > Request URL 주소
    down_url = 'http://data.krx.co.kr/comm/fileDn/download_csv/download.cmd'

     

    3.  download.cmd > Payload를 들어가면 Form Data가 있는데, 'code: ~~~ '형태로 되어 있는 것을 확인할 수 있습니다.

    code: 뒷부분의 ~~~~ 부분이 generate.cmd를 크롤링해온 정보라고 생각하시면 이해하시기 용이합니다.generate.cmd를 불러온 otp 변수를 전달하기 위해 딕셔너리 형태의 변수를 선언해줍니다.

    4.  requests 라이브러리를 이용해 정보를 받아옵니다.

    download.cmd > Payload > From Data 확인

    down_data = {
        'code' : otp
    }
    
    # requests로 data 전달
    down_stock_info = requests.post(down_url, params=down_data, headers=headers)

     

    4-4. DataFrame으로 저장 후 Return

    이제 download.cmd의 정보를 데이터프레임 형태로 저장 후 Return 해줍니다.

    # 다운받은 csv를 DataFrame 형태로 저장
    stock_info = pd.read_csv(BytesIO(down_stock_info.content), encoding='EUC-KR')
    
    # DataFrame return
    return stock_info

     

    4-5. 정상적으로 함수가 동작하는지 확인하기

    열심히 함수를 만들었으니 제대로 동작하는지 확인해볼 시간입니다.함수를 호출한 이후 데이터프레임을 출력해봅니다.

    # 함수 호출
    stock_info = mk_all_stock_info()
    
    # 데이터 프레임 확인
    stock_info

    함수 호출 및 데이터프레임 출력 결과

     

    5. 데이터프레임 엑셀 저장

     

    데이터프레임으로 불러오는 데 성공했으니, 엑셀로 저장까지 해보겠습니다.

     

    5-1. 엑셀 생성 및 저장 경로 지정해주기

    우선 저장하고자 하는 경로에 엑셀 파일을 새로 생성해줍니다.(openpyxl로 만들 수도 있지만 편의상 미리 만들어두었습니다.)엑셀 파일 경로는 만들어둔 엑셀을 우클릭해 속성 > 위치로 쉽게 확인할 수 있습니다.

    속성에 나오는 위치를 전부 복사해 '원하는 경로 설정' 부분에 넣어주면 됩니다.

    엑셀 위치 복사

    # 엑셀 파일 저장 경로 설정 *** 미리 엑셀 파일은 만들어야 합니다 ***
    save_path = r"원하는 경로 설정\stock_info.xlsx"

     

    5-2. 엑셀 저장

    우선 저장하고자 하는 경로에 엑셀 파일을 새로 생성해줍니다.

    경로 설정을 잘하셨다면, 데이터프레임을 엑셀로 저장해봅시다.

    저는 dataframe_to_rows라는 함수를 사용했습니다.

    dataframe_to_rows는 데이터프레임을 한 줄씩 엑셀에 작성해주는 함수라고 생각하면 편합니다.

    모두 엑셀에 작성했다면 마지막 save함수를 통해서 저장을 해주어야 합니다.

    # 엑셀 오픈
    wb = openpyxl.load_workbook(save_path)
    
    # 엑셀 시트 지정
    ws = wb['Sheet1']
    
    # 데이터프레임 'stock_info'를 한줄씩 엑셀에 작성
    for r in dataframe_to_rows(stock_info, index=False, header=True):
        ws.append(r)
    
    # 엑셀 저장
    wb.save(save_path)

     

    이상으로 KRX 정보데이터시스템에서 전종목 기본정보 가져오기를 해보았습니다.

    다음에는 이번에 크롤링한 기본정보를 활용해 종목명을 입력하면 표준코드, 종목코드를 찾아보는 글을 작성해보고자 합니다.

    어렵고 복잡해 보일 수 있지만 다들 잘 따라오셨기를 바랍니다.

     

    감사합니다.

     

     

     

     

    반응형

    댓글

Designed by Tistory.