ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [데이터수집] 내일은 휴장일? 한국거래소 확인 (1) download
    Python/텔레그램봇:채권모니터링 2020. 12. 23. 17:16

    봇을 돌리려면 오늘 휴장인지 정보가 필요하다.

    해당 정보는 한국거래소 - MarketData - 시장정보 - 시장동향 - 증시일정 - 휴장일에서

      1) 엑셀파일로 다운로드 후 확인

      2) 조회 방식으로 확인

    2가지 방법으로 확인이 가능하다.

    엑셀파일 다운로드의 경우 채권정보를 가져왔던 방식과 동일하게 OTP 발급 스크립트를 추가해 처리하면 된다.


     

    먼저 엑셀파일로 확인해본다.

     

    실패한 엑셀파일 1차 시도

    이쪽을 참고했다: nbviewer.jupyter.org/urls/financedata.github.io/posts/pandas-market-days-krx.ipynb

    위 블로그에서는 OTP 발급절차 없이 바로 url로 접속해서 데이터를 확보했다.

    바로 접속한 url은 이렇다: marketdata.krx.co.kr/contents/MKD/01/0110/01100305/MKD01100305.jsp

     

    OTP가 없어도 되는건가?! 하고 직접 접속을 했으나

    개발자도구의 네트워크 부분을 보니 실패하고 GenerateOTP로 넘어가서 데이터를 받았다.

    블로그를 자세히 읽어보니 직접 엑셀파일을 다운로드 받아서 처리하신 듯하다.

    포기하고 OTP 요청 방식으로 재시도했다.

     

    OTP로 엑셀파일 다운로드 2차 시도

    데이터수집 방법은 지난번([데이터수집] 한국거래소 정보 가져오기)과 같다.

     

     

    GET GenerateOTP

    otp_headers = {'User-Agent': 'Mozilla/5.0 (Windows Phone 10.0; Android 4.2.1; Microsoft; Lumia 950)',
                    'Referer': 'http://marketdata.krx.co.kr/contents/MKD/01/0110/01100305/MKD01100305.jsp'
                  }
    otpURL = 'http://marketdata.krx.co.kr/contents/COM/GenerateOTP.jspx?name=fileDown&filetype=xls&url=MKD/01/0110/01100305/mkd01100305_01&search_bas_yy=2020&gridTp=KRX&pagePath=%2Fcontents%2FMKD%2F01%2F0110%2F01100305%2FMKD01100305.jsp'
    
    otp = requests.get(url=otpURL, headers=otp_headers)
    
    print(otp.content)

    이번에도 otpURL과 headers의 Referer 정보는 Network에서 GenerateOTP 파일의 url을 확인해서 얻었다.

     

    Download file

    download_headers = {'User-Agent': 'Mozilla/5.0 (Windows Phone 10.0; Android 4.2.1; Microsoft; Lumia 950)',
                     'Referer': 'http://marketdata.krx.co.kr/'
                   }
    
    form_data = {
                  'code': otp.content  # 위에서 획득한 OTP를 여기 넣어주자
                 }
                 
    downloadURL = 'http://file.krx.co.kr/download.jspx'
    
    data = requests.get(downloadURL, form_data, headers=download_headers).content
    # 엑셀파일은 바이너리로 들어오기 때문에 content로 받아야한다. text로 받았더니 깨졌다.
    
    filePath = './file.xlsx'
    with open(filePath, "wb") as t: # 마찬가지로, 엑셀파일이라서 바이너리로 써야한다
        t.write(data)
    

    csv가 아니기 때문에 로우데이터 확인은 엑셀프로그램이 없으면 불가능하다.

    하지만 다운받은 데이터를 pandas.read_excel(파일경로)로 열면 확인할 수 있다.

    pandas에서 엑셀을 읽으려면 xlrd 패키지가 필요하니 우선 설치를 하고

    # pip install xlrd

    xlrd는 설치만 돼있으면 pandas에서 알아서 불러다 쓰기 때문에 따로 import는 안 해도 된다.

    나머지는 read_csv에서 했던 것처럼 처리하면 된다.

    import pandas as pd
    
    # filePath = "./file.xlsx" # 위에서 받은 파일
    dataframe = pd.read_excel(filePath)
    print(dataframe)

    예쁘게 잘 나온다.

    print(dataframe) 출력 결과

    일자 및 요일의 리스트만 필요하다면

    print(list(dataframe['일자 및 요일']))
    '''
    ['2020-01-01', '2020-01-24', '2020-01-27', '2020-04-15', '2020-04-30', '2020-05-01',
    '2020-05-05', '2020-08-17', '2020-09-30', '2020-10-01', '2020-10-02', '2020-10-09',
    '2020-12-25', '2020-12-31']
    '''

     

     

    # 전체 코드

    import requests
    import pandas as pd
    
    userAgent = 'Mozilla/5.0 (Windows Phone 10.0; Android 4.2.1; Microsoft; Lumia 950)'
    # otp 정보
    otpReferer = 'http://marketdata.krx.co.kr/contents/MKD/05/0502/05020201/MKD05020201.jsp'
    otpURL = 'http://marketdata.krx.co.kr/contents/COM/GenerateOTP.jspx?name=fileDown&filetype=xls&url=MKD/01/0110/01100305/mkd01100305_01&search_bas_yy=2020&gridTp=KRX&pagePath=%2Fcontents%2FMKD%2F01%2F0110%2F01100305%2FMKD01100305.jsp'
    # 다운로드 정보
    downloadReferer = 'http://marketdata.krx.co.kr/'
    downloadURL = 'http://file.krx.co.kr/download.jspx'
    # 다운받은 엑셀 데이터 저장할 경로
    filePath = "./file.xlsx"
    
    # GET GenerateOTP 
    otp_headers = {'User-Agent': userAgent,
                    'Referer': otpReferer
                  }
    otp = requests.get(url=otpURL, headers=otp_headers)
    # print(otp.content)  # OTP 잘 받아지는지 확인
    
    # Download file
    download_headers = {'User-Agent': userAgent,
                     'Referer': downloadReferer
                   }
    form_data = {
                  'code': otp.content  # 위에서 획득한 OTP를 여기 넣어주자
                 }  
    data = requests.get(downloadURL, form_data, headers=download_headers).content
    
    with open(filePath, "wb") as t: # 엑셀파일이라서 바이너리로 써야한다
        t.write(data)
    filePath = "./file.xlsx"
    dataframe = pd.read_excel(filePath)
    
    print(dataframe)
    print(list(dataframe['일자 및 요일']))

     


    otpURL 변수 보충

    otpURL = 'http://marketdata.krx.co.kr/contents/COM/GenerateOTP.jspx?name=fileDown&filetype=xls&url=MKD/01/0110/01100305/mkd01100305_01&search_bas_yy=2020&gridTp=KRX&pagePath=%2Fcontents%2FMKD%2F01%2F0110%2F01100305%2FMKD01100305.jsp'

    처음 작성시에는 확인하지 못했는데, GenerateOTP에 전달되는 변수 중에 search_bas_yy이 있다.

    조회할 연도를 지정하는 변수다.

    2021년 데이터를 보고 싶다면 해당 부분을 search_bas_yy=2021로 바꿔야 한다.

     

    조회할 시점을 기준으로 해당 연도를 조회하기 위해서는, 아래처럼 함수 형태로 작성 후 otpURL()로 호출하면 된다.

    import time
    
    def otpURL():
        return 'http://marketdata.krx.co.kr/contents/COM/GenerateOTP.jspx?' \
               + 'name=fileDown&filetype=xls&url=MKD/01/0110/01100305/mkd01100305_01' \
               + '&search_bas_yy=' + str(time.gmtime().tm_year) \
               + '&gridTp=KRX&pagePath=%2Fcontents%2FMKD%2F01%2F0110%2F01100305%2FMKD01100305.jsp'

     

    댓글

Designed by Tistory.