-
[데이터수집] 내일은 휴장일? 한국거래소 확인 (2) 조회Python/텔레그램봇:채권모니터링 2020. 12. 26. 21:03
봇을 돌리려면 오늘 휴장인지 정보가 필요하다.
해당 정보는 한국거래소 - MarketData - 시장정보 - 시장동향 - 증시일정 - 휴장일에서
1) 엑셀파일로 다운로드 후 확인
2) 조회 방식으로 확인
2가지 방법으로 확인이 가능하다.
조회도 파일다운로드처럼 OTP 발급과정을 거쳐서 처리하면 된다.
Nowtime값을 GenerateOTP에 전달 -> OTP 발급 -> OTP를 MKD99000001에 전달 -> 조회 데이터 리턴
조회에 필요한 Nowtime은 epoch time이므로 int(round(time.time() * 1000))을 정의해서 처리한다.
이번에는 다운로드 대신 조회 기능을 사용해볼 예정이다.
개발자 도구의 네트워크 부분을 열어보니 조회에는 Nowtime.jspx라는 단계가 하나 더 있다.
숫자가 epoch time 같긴 한데 뭔가 로직이 더 있는듯하다. 실제 찍어본 시간과는 약간 차이가 있다.
사이트에 접속하면 Nowtime.jspx가 실행되면서 현재 시간이 epoch time으로 전달되고,
그후에 다시 조회하면 10초 이상 지났는데도 아까 전달되었던 Nowtime 값에서 +1 식으로 갱신된다.
테스트 삼아 현재 epoch time을 보냈을 때 OTP가 정상 반환되었기 때문에, epoch time을 그대로 전달하는 방식을 썼다.
epoch time이 13자리로 전달되기 때문에 python에서 포맷을 작성하고
[참조] stackoverflow.com/questions/5998245/get-current-time-in-milliseconds-in-python
import time t = lambda: int(round(time.time() * 1000)) print(t()) # 1608526699266
GenerateOTP를 실행한다.
import requests import time nowTime = lambda: str(int(round(time.time() * 1000))) # url로 보내야해서 str 한번 더 씌움 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?bld=MKD/01/0110/01100305/mkd01100305_01&name=form&_=' otp = requests.get(url=otpURL + nowTime(), headers=otp_headers) # print(otp.content)
otpURL과 headers의 Referer 정보는 Network에서 GenerateOTP 파일의 url을 확인해서 얻었다.
OTP 확인이 완료되었으니, MKD99000001에 요청을 보내본다. 역시 post 요청이기 때문에 정보를 form data로 보내줘야 한다.
호출시마다 search_bas_yy를 갱신해야 하므로 함수로 구성했다.
* 엑셀로 다운로드 할 때는 MKD99000001가 아니라 GenerateOTP 때 gridTp, search_bas_yy, pagePath 변수를 전달해서, 단순 url 쿼리스트링 복사로 처리했었다.
download_headers = {'User-Agent': 'Mozilla/5.0 (Windows Phone 10.0; Android 4.2.1; Microsoft; Lumia 950)', 'Referer': 'http://marketdata.krx.co.kr/mdi' } def getFormData(): return { 'gridTp': "KRX", 'search_bas_yy': str(time.gmtime().tm_year), # '2020' # 년도 'code': otp.content, # 위에서 획득한 OTP를 여기 넣어주자 'pagePath': '/contents/MKD/01/0110/01100305/MKD01100305.jsp' } downloadURL = 'http://marketdata.krx.co.kr/contents/MKD/99/MKD99000001.jspx' data = requests.get(downloadURL, getFormData(), headers=download_headers) print(data.json()) # 데이터는 제이슨 타입으로 들어온다
예쁘게 잘 나온다.
일자 및 요일의 리스트만 필요하다면
jsonData = data.json() print([each['calnd_dd_dy'] for each in jsonData['block1']]) ''' ['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-1 0-02', '2020-10-09', '2020-12-25', '2020-12-31'] '''
# 전체 코드
import requests import time userAgent = 'Mozilla/5.0 (Windows Phone 10.0; Android 4.2.1; Microsoft; Lumia 950)' # otp url 정보 otpReferer = 'http://marketdata.krx.co.kr/contents/MKD/01/0110/01100305/MKD01100305.jsp' otpURL = 'http://marketdata.krx.co.kr/contents/COM/GenerateOTP.jspx?bld=MKD/01/0110/01100305/mkd01100305_01&name=form&_=' # view url 정보 viewReferer = 'http://marketdata.krx.co.kr/mdi' viewURL = 'http://marketdata.krx.co.kr/contents/MKD/99/MKD99000001.jspx' otp_headers = { 'User-Agent': userAgent, 'Referer': otpReferer } view_headers = { 'User-Agent': userAgent, 'Referer': viewReferer } def getOTP(otpURL, otp_headers): nowTime = str(int(round(time.time() * 1000))) # 함수 안에 넣으면서 람다를 지웠다 otp = requests.get(url=otpURL + nowTime, headers=otp_headers) return otp.content def getFormData(OTP): return { 'gridTp': "KRX", 'search_bas_yy': str(time.gmtime().tm_year), # '2020' # 년도 'code': OTP, # 위에서 획득한 OTP를 여기 넣어주자 'pagePath': '/contents/MKD/01/0110/01100305/MKD01100305.jsp' } def getData(viewURL, FormData, view_headers): return requests.get(viewURL, FormData, headers=view_headers) def getHolidayList(otp_headers, view_headers, otpURL, viewURL): OTP = getOTP(otpURL, otp_headers) time.sleep(1) formData = getFormData(OTP) data = getData(viewURL, formData, view_headers).json() return [each['calnd_dd_dy'] for each in data['block1']] def main(): hList = getHolidayList(otp_headers, view_headers, otpURL, viewURL) print(hList) if __name__ == '__main__': main()
'Python > 텔레그램봇:채권모니터링' 카테고리의 다른 글
[Summary] 텔레그램봇: 채권모니터링 Review (0) 2020.12.31 [데이터수집] 내일은 휴장일? 한국거래소 확인 (1) download (0) 2020.12.23 [스케쥴링] 특정 시간에 실행하기 - 휴장일 커버 (0) 2020.12.21 [python] 모듈 정리하기 (0) 2020.12.18 [TelegramBot] 봇 생성과 메시지전송 (0) 2020.12.18