[ECOS API] 한국은행 경제통계 API 이용 (2) json
원래는 API 기본 값인 xml로 데이터를 처리하다가,
뒤늦게 json타입도 지원되는 걸 발견하고 환승하면서 코드를 class로 정리해서 모아두기로 했다.
주요 목적은 인증키와 STAT_CODE와 ITEM_CODE1, count 정보를 담은 객체를 만들어두고,
필요할 때마다 최근 데이터를 불러오는 함수 작성하기. 아래와 같은 모양이다.
setting = {
'key': 'asdf'
'dataType': 'json',
'language': 'kr',
} # 이쪽에 기본 정보를 정리해두고
corpBondAAm = Ecos(setting, STAT_CODE='060Y001', ITEM_CODE1='010300000', count=19)
print(corpBondAAm.getLatest()) # {'20201211': 2.215}
corpBondBBBm = Ecos(setting, STAT_CODE='060Y001', ITEM_CODE1='01032000', count=20)
print(corpBondBBBm.getLatest()) # {'20201211': 8.626}
작성해야할 url 구문은 아래와 같다. 이중 채워야할 부분은 일자타입, 시작/종료일자.
http://ecos.bok.or.kr/api/StatisticSearch/인증키/json/kr/1/1/STAT_CODE/일자타입/시작일자/종료일자/ITEM_CODE1/
데이터는 1건씩만 받을 것이라 STAT_CODE 앞의 부분은 /1/1/로 채웠다.
시작/종료일자는 가장 최근 데이터가 언제인지를 알아야 채울 수 있다.
이 정보는 통계 세부항목 목록(StatisticItemList) 쪽에 url을 보내면 알 수 있다.
시장금리(일별)(060Y001) 데이터에 세부항목이 23건이 있고, 내가 찾고 싶은 회사채(3년,AA-)(010300000) 데이터는 그중 19번이다.
count 입력을 생략하도록 할까 하다가, 어차피 서비스 가능한 통계코드를 찾다보면 찾아야해서 그냥 입력하기로 했다.
http://ecos.bok.or.kr/api/StatisticItemList/인증키/json/kr/19/19/060Y001/
위 쿼리를 보내면 이런 데이터를 얻을 수 있다.
{
"StatisticItemList": {
"list_total_count": 23,
"row": [
{
"END_TIME": "20201211",
"DATA_CNT": 6633,
"GRP_NAME": "항목선택",
"CYCLE": "DD",
"STAT_NAME": "4.1.1 시장금리(일별)",
"ITEM_NAME": "회사채(3년,AA-)",
"GRP_CODE": "Group1",
"STAT_CODE": "060Y001",
"ITEM_CODE": "010300000",
"START_TIME": "19950103",
"P_ITEM_CODE": ""
}
]
}
}
이제 여기서jsondata['StatisticItemList']['row'][0]['END_TIME']값 20201211을
위의 시작/종료일자에 채워서 다시 보내면 된다.
그러면 아래와 같은 데이터를 얻을 수 있고, 값은 jsondata['StatisticSearch']['row'][0]['DATA_VALUE']로 접근하면 된다.
{
"StatisticSearch": {
"list_total_count": 1,
"row": [
{
"UNIT_NAME": "연%",
"STAT_NAME": "4.1.1 시장금리(일별)",
"ITEM_CODE1": "010300000",
"STAT_CODE": "060Y001",
"ITEM_CODE2": " ",
"ITEM_CODE3": " ",
"ITEM_NAME1": "회사채(3년,AA-)",
"ITEM_NAME2": " ",
"DATA_VALUE": "2.215",
"ITEM_NAME3": " ",
"TIME": "20201211"
}
]
}
}
함수를 작성하면 이렇다.
import requests
class Ecos:
def __init__(self, Key, STAT_CODE, ITEM_CODE1, count):
# count: StatisticItemList에서 ITEM_CODE1이 STAT_CODE의 몇 번째 항목인지
self.Key = Key
self.STAT_CODE = STAT_CODE
self.ITEM_CODE1 = ITEM_CODE1
self.base = 'http://ecos.bok.or.kr/api/'
self.count = count
def getJSON(self, url):
return requests.get(url).json()
def getDate(self): # 최근 일자 구하기
url = self.base + 'StatisticItemList/' + self.Key \
+ '/json/kr/' + str(self.count) + '/' + str(self.count) \
+ '/' + self.STAT_CODE
data = self.getJSON(url)
return (data['StatisticItemList']['row'][0]['END_TIME'],
data['StatisticItemList']['row'][0]['CYCLE'])
def getLatest(self): # 목표인 금리 데이터 구하기
date, cycle = self.getDate()
url = self.base + 'StatisticSearch/' + self.Key \
+ '/json/kr/1/1/' + self.STAT_CODE + '/' + cycle + '/' \
+ date + '/' + date + '/' + self.ITEM_CODE1
data = self.getJSON(url)
returnDict = {
'date': date,
'value': float(data['StatisticSearch']['row'][0]['DATA_VALUE'])
}
return returnDict
Key = ''
corpBondAAm = Ecos(Key, STAT_CODE='060Y001', ITEM_CODE1='010300000', count=19)
print(corpBondAAm.getLatest()) # {'date': '20201211', 'value': 2.215}
corpBondBBBm = Ecos(Key, STAT_CODE='060Y001', ITEM_CODE1='010320000', count=20)
print(corpBondBBBm.getLatest()) # {'date': '20201211', 'value': 8.626}
getLatest() 메소드 보충
20년 12월 15일 오후 4시 30분 경에 코드를 돌리다가 에러가 나는 것을 확인했다.
StatisticItemList 쪽 END_TIME은 '20201215'로 업데이트 되었는데,
StatisticSearch 쪽에는 아직 데이터가 추가되지 않아서 에러가 났다. 이 경우 값은 이렇게 반환된다.
{"RESULT":{"MESSAGE":"해당하는 데이터가 없습니다.","CODE":"INFO-200"}}
데이터는 4시 40분 경 업데이트 되었으니 정규 마켓타임이 아니라서 실제 불편함은 없을 것 같아서 간단히만 수정했다.
확인이 완료된 최근 일자를 validDate에 저장해두고 불러쓰는 형식으로 변경:
def getLatest(self): # 목표인 금리 데이터 구하기
date, cycle = self.getDate()
url = self.base + 'StatisticSearch/' + self.Key \
+ '/json/kr/1/1/' + self.STAT_CODE + '/' + cycle + '/' \
+ date + '/' + date + '/' + self.ITEM_CODE1
data = self.getJSON(url)
if "RESULT" in data:
url = url.replace(date, self.validDate, 2)
data = self.getJSON(url)
returnDict = {
'date': date,
'value': float(data['StatisticSearch']['row'][0]['DATA_VALUE'])
}
self.validDate = date
return returnDict