ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • KRX에서 상장 회사 검색 갈무리(크롤링)하는 법
    Python/파이썬과 주식 2019. 11. 4. 23:05
    반응형

    * KRX의 정책의 변화에 따라 작동되지 않을 수도 있습니다. 

    * 실제 투자에 사용하지 마십시오. 

     

    앞서 알려드린 KIND의 본진이죠?

     

    한국거래소(KRX)에서도 상장회사 검색을 통해 목록을 구할 수 있습니다. 

    http://marketdata.krx.co.kr/mdi#document=040601

     

    KRX - 상장회사검색

    KIND의 목록보다 좀 더 유용한 정보(상장주식수, 자본금)가 많고 깔끔하네요. 

     

    이 화면에서 엑셀 파일을 받으신 뒤 파이썬으로 데이터를 정리하셔도 좋을 것 같습니다만... (이걸 추천합니다.)

     

    바로 파이썬에서 엑셀 데이터를 가져올 수도 있습니다. (복잡해요.)

     

    파이썬의 기본 패키지인 io의 BytesIO를 이용하면 메모리에 있는 bytes 데이터(b'문자열')를 파일처럼 이용할 수 있습니다. 

     

    일단 위 화면에서 엑셀 버튼을 눌러 크롬의 개발자 도구 네트워크 탭에서 어떤 변화가 모니터링되었는지 확인하겠습니다. 

     

    조금 난이도가 있죠? 

     

    'Excel' 버튼을 클릭하면 'GenerateOTP.jspx'가 호출되고 이 'GenerateOTP.jspx'가 iframe 내의 'download.jspx'를 호출해서 엑셀 파일이 열림을 알 수 있습니다. (Waterfall 참고)

     

     

    최종적으로 download.jspx의 URL을 이용하면 엑셀 파일을 받을 수 있을 것 같습니다. 

    OTP가 조금 걸리긴 합니다. 시간이 지나면 아래 링크가 무효해 질 것 같지 않습니까?

    은행의 OTP 번호처럼... 

     

    http://file.krx.co.kr/download.jspx?code=vq5kGmOr8eCwmRuXQ%2BDSaJsN99to9K6bfazH3jC%2BZIEfkN8ph00A9LAPKrpUs1xp8tJpYXgeUu8h33%2BXt5rILLDkpk43BzgzAGWYf%2BfsDyZBZSq2WHd4Csqf6fU9uM0ySOVC%2BLxZyRymuCvuNLFr%2FKdZ1s%2Bd7VR4Bf173nkm0bz6ii2GXo5aYv0F%2B6QZdTNMSmRibDHnbXm%2FgjwgHgj5m1EKDgVc444eDbrW%2FoKJamY9C8dHXySWEC3xACIPYHk2VOLy9Y8eKzNaQccfWD9FSPTRE7aCStGMXhQqBxDux0uznjENM53%2BeqR0zqGdPN9yK9%2FyRsS2IxID7YQ1c3GqvPLpwYvaQ8TtuIBA5NMlZ2irEBOPC1JgHI0qMsA4%2F7MItDUq7GIEEBUYqk8TZHfi36aLLM%2BvSehcISEI2XLaZvDc55CPrFUOjpsomCzBWw74oj%2FOcxLjk9BJh59yzaEex6zfibkAfWfpwVp9qQAT8shCGoUq2AZ7q7E5T6fm%2FEX0B6l9lrFnvtgF3SSwRrE0ti1KwyvR7oTzhXxA%2FDMsHSTLlc01q5zUE0GT9s0SRU8Z5KbZboyfFCrovYTE7r2QxQYrjN0O4pFETsk7c0JMH9svOcXoJW9dum%2BmEdIiwEt9

     

    그런데 위 링크를 클릭해도 브라우저에 아무 것도 안 보입니다. 

    서버에서 헤더의 리퍼러를 체크하네요.

    리퀘스트 시 헤더에 리퍼러를 끼워줘야 합니다. 

    (referrer가 맞는 철자, HTML 정의에 referer로 오타.)

     

     

     

    from io import BytesIO
    from urllib import request
    
    import pandas as pd
    
    req_url = 'http://file.krx.co.kr/download.jspx?' \
              'code=vq5kGmOr8eCwmRuXQ%2BDSaJsN99to9K6bfazH3jC%2BZIEfkN8ph00A9LAPKrpUs1xp8tJpYXgeUu8h33%2BXt5rILLDkpk43B' \
              'zgzAGWYf%2BfsDyZBZSq2WHd4Csqf6fU9uM0ySOVC%2BLxZyRymuCvuNLFr%2FKdZ1s%2Bd7VR4Bf173nkm0bz6ii2GXo5aYv0F%2B6Q' \
              'ZdTNMSmRibDHnbXm%2FgjwgHgj5m1EKDgVc444eDbrW%2FoKJamY9C8dHXySWEC3xACIPYHk2VOLy9Y8eKzNaQccfWD9FSPTRE7aCStG' \
              'MXhQqBxDux0uznjENM53%2BeqR0zqGdPN9yK9%2FyRsS2IxID7YQ1c3GqvPLpwYvaQ8TtuIBA5NMlZ2irEBOPC1JgHI0qMsA4%2F7MIt' \
              'DUq7GIEEBUYqk8TZHfi36aLLM%2BvSehcISEI2XLaZvDc55CPrFUOjpsomCzBWw74oj%2FOcxLjk9BJh59yzaEex6zfibkAfWfpwVp9q' \
              'QAT8shCGoUq2AZ7q7E5T6fm%2FEX0B6l9lrFnvtgF3SSwRrE0ti1KwyvR7oTzhXxA%2FDMsHSTLlc01q5zUE0GT9s0SRU8Z5KbZboyfF' \
              'CrovYTE7r2QxQYrjN0O4pFETsk7c0JMH9svOcXoJW9dum%2BmEdIiwEt9'
    
    headers = {'Referer': 'http://marketdata.krx.co.kr/mdi'}
    
    req = request.Request(req_url, headers=headers)
    byte_data = request.urlopen(req).read()
    
    df = pd.read_excel(BytesIO(byte_data))
    print(df.head())

     

    OTP 문제가 없다면 다운로드할 수 있습니다. 

    만약 문제가 있다면... 

    Step By Step 이죠 머.. 

    from io import BytesIO
    from urllib import request
    
    import pandas as pd
    
    req_url = 'http://marketdata.krx.co.kr/contents/COM/GenerateOTP.jspx?' \
              'name=fileDown' \
              '&filetype=xls' \
              '&url=MKD/04/0406/04060100/mkd04060100_01' \
              '&market_gubun=STK' \
              '&isu_cdnm=%EC%A0%84%EC%B2%B4' \
              '&sort_type=A' \
              '&lst_stk_vl=1' \
              '&isu_cdnm=%EC%A0%84%EC%B2%B4' \
              '&pagePath=%2Fcontents%2FMKD%2F04%2F0406%2F04060100%2FMKD04060100.jsp'
    
    req = request.Request(req_url)
    code = request.urlopen(req).read().decode()
    req_url = 'http://file.krx.co.kr/download.jspx?code=' + code
    headers = {'Referer': 'http://marketdata.krx.co.kr/mdi'}
    req = request.Request(req_url, headers=headers)  # 헤더(리퍼러) 추가
    byte_data = request.urlopen(req).read()
    df = pd.read_excel(BytesIO(byte_data))
    del df['번호']
    df['종목코드'] = df['종목코드'].map(lambda x: f'{x:0>6}')
    df['업종코드'] = df['업종코드'].map(lambda x: f'{x:0>6}')
    df['상장주식수(주)'] = df['상장주식수(주)'].str.replace(",", "")
    df['상장주식수(주)'] = pd.to_numeric(df['상장주식수(주)'])
    df['자본금(원)'] = df['자본금(원)'].str.replace(",", "")
    df['자본금(원)'] = pd.to_numeric(df['자본금(원)'])
    print(df.head())

    * 시장 구분: market_gubun: STK, KSQ, KNX

    반응형
Designed by Tistory.