한국은행 ECOS 통계를 R에서 Open API로 가져오기
매월, 업무상 한국은행 경제통계시스템(ECOS)에 들어가 국고채 수익율을 조회할 일이 있는데, 이게 좀 귀찮다. 일단 업무용 PC에서는 인터넷 접속이 안되기에 가상 인터넷 망으로 들어간 다음(시간 소요), ecos.bok.or.kr에 접속하여 국고채 수익률 통계의 종류를 고르고, 대상 기간을 입력하여 통계를 조회한 다음 이를 엑셀로 다운받아 다시 인터넷 망에서 업무 망으로 전송하여 내 PC로 가져오는 과정..
글로 적어도 귀찮네..
그런데 이게 우리 외사 대부분의 직원들이 외부 데이터를 가져오고 있는 방식이겠지.
사내 빅데이터 시스템에 가면 일부 한은 통계가 적재되어 있다고는 들었는데 그마저도 일부에 한할거고, 접속 과정 등 때문에 나도 아직 제대로 해보진 못했다. 접속 권한 획득부터 그 사용법 숙지에, 실제로 시도해보는 것도 또 일이기에, 한국은행 API를 활용하여 R에서 직접 필요한 데이터를 가져와보기로 했다. 이런건 요즘 Python으로도 많이 하더만.
R에서 API를 쓰는 것은 이미 2020년에 네이버 API로 블로그 데이터를 가져오는 걸 해봤었는데, 그것도 3년이나 되었다. 그리고 업무에 쓰는 건 아니었기에, 호기심 한번 충족하고 포스팅 적은 걸로 끝.
네이버 Open API with R : 블로그 검색 결과 호출하여 워드클라우드 생성하기
지금은 조금 뜸 한 듯 하지만, 얼마 전까지 사무실에서 RPA, API가 화두일 때가 있었다. 사무실에서...
blog.naver.com
이번건 업무상 필요한 거니 계속 보게 되겠지? 그 과정에서 더 공부하게 될테고, 더 편하게 쓸수 있게 될거다.
1. 한국은행 경제통계시스템(ECOS) 개요
ECOS는 한국은행이 이용자 편의를 위해 2004년 1월부터 운용해온 통계 전용 인터넷 홈페이지로, ECOnomic Statistics System의 약어란다.이걸 찾으려고 한국은행 보도자료까지 뒤져봤네..
한국은행의 통계전용 인터넷 홈페이지(ECOS) 개편 | 보도자료(상세) | 커뮤니케이션 | 한국은행 홈
한국은행과 관련된 보도자료 제공 게시판
www.bok.or.kr
2. 한국은행 ECOS Open API 서비스 이용 방법
ECOS Open API는 아예 홈페이지도 별도로 있는데, 아래로 접속하면 된다.
한국은행 Open API 서비스
ecos.bok.or.kr
위의 한은 사이트에서 요약된 API 서비스 이용 방법은 아래와 같고,
가장 먼저 해야하는 것은 인증키 신청인데, 클릭해보면 동의후 아래와 같은 회원 가 비슷한 절차로 인증키를 발급받을 수 있다.
인증키를 발급 받은 다음에는, 어떤 서비스를 어떻게 이용할 수 있는지를 확인해야 한다.
내가 하고 싶은건 '특정 기간의 국고채 수익률을 조회하는 것'인데, 이는 서비스 목록에서 '통계 조회 조건 설정' 부분을 참고하면 된다.
이를 클릭하면 개발 가이드 메뉴의 '개발 명세서'로 연결되고, 개발 명세서에서는 요청인자와 출력값을 확인할 수 있다.
스크롤을 아래로 내리면 조회되는 출력값 탭 옆의 샘플 URL 탭에서는 API 주소와 형식을 확인할 수도 있다.
개발가이드 메뉴에는 ' 언어별 개발 가이드'도 있는데, 여기서는 Python과 R 예시도 있으니 참고
파일 다운로드하여 실행해볼 수도 있음
3. R에서 국고채 수익률을 API로 가져오기
특정 통계코드표에 대해 일정 기간 동안의 데이터를 가져오려면 서비스 목록에서 '통계 조회 조건 설정' 부분을 참조하면 된다. 위에서 본 개발 가이드의 '개발 명세서'상의 요청인자를 설정하면 되는데, 여기서는 요청 유형과 통계표코드에 유의하면 됨
요청유형에는 xml과 json이 있는데, 둘다 잘 모르니 시도는 다 해봤고, 이후 변환이 json이 더 편한 것 같아 나는 json으로 해봤다.
* 이부분은 추가 확인 필요
통계표코드는 개발가이드의 '통계코드검색'에서 확인할 수 있는데, ECOS를 그냥 이용할 때처럼 목록에서 찾아 들어가든지, 아니면 검색으로도 알아낼 수 있다.
아래의 왼쪽 통계표에서 '국고채'로 검색한 결과. 일별 시장금리에 해당하는 통계표코드는 '817Y002'고, 주기는 '일별(D)'임을 확인할 수 있으며,
오른쪽 통계 항목에서는 국고채(1년)~국고채(30년)에 대한 코드와 단위를 확인할 수 있다. 예를 들어 국고채(1년) 수익률은 01090000.
[참고]
다수의 통계항목코드 조회는 현재 BOK API에서 지원하지 않는다니,
아예 통계항목코드를 지정하지 않고 특정 통계표의 모든 통계항목을 조회하거나,
url을 여러개 설정해야 한다고
(출처 : BOK API QnA)
https://ecos.bok.or.kr/api/#/ParticipatoryCommunication/QNA/0000011841
4. R 코드 실습
먼저 필요한 패키지들 부터.
- 설정한 url로 웹에서 데이터를 가져오려면 httr 패키지가 필요하고,
- 조회 결과를 json을 받아 이를 파싱하는데 jsonlite 패키지,
- 그리고 sql로 데이터를 요약하고 정리하는데 sqldf 패키지를 썼다.
R 좀 쓴다 하면 dplr 패키지를 써야 하는데, 나는 아직도 업무에서 많이 쓰는 sqldf를 주력으로 씀..
# 필요한 패키지들
library(httr)
library(jsonlite)
library(sqldf)
이후 기본 URL과 요청인자들을 설정한다.
- 인증키(ID)에는 위에서 발급받은 것을 넣으면 되고,
- 통계표는 국고채(817Y002), 통계항목코드는 국고채1년(010190000),
- 요청건수는 1~1000건,
- 일자는 23.1.1부터 23.7.31까지로 설정했다.
# 기본 url
url_base = "http://ecos.bok.or.kr/api/StatisticSearch"
# 요청인자들
id = "<< 사용자별 인증키 >>"
요청유형 = "json"
언어구분 = "kr"
요청시작건수 = "1"
요청종료건수 = "1000"
통계표코드 = "817Y002"
주기 = "D"
검색시작일자 = "20230101"
검색종료일자 = "20230731"
통계항목코드1 = "010190000"
이어서 paste() 함수로 기본 url과 요청인자들을 조합하고,
# paste() 함수를 이용한 url 조합
url = paste(url_base,id,요청유형,언어구분,요청시작건수,요청종료건수,통계표코드,주기,검색시작일자,검색종료일자,통계항목코드1, sep="/")
httr 패키지의 GET() 함수를 이용하여 조합한 url에 대한 데이터를 API 서비스로 가져온다.
# 결과 송수신
api_result = GET(url)
# 송수신 결과
api_result
결과는 아래와 같이 조회되는데, status = 200이면 성공이라고
Response [http://ecos.bok.or.kr/api/StatisticSearch/<< 인증키 >>/json/kr/1/1000/817Y002/D/20230731/20230731]
Date: 2023-08-06 02:52
Status: 200
Content-Type: application/json; charset=UTF-8
Size: 7.68 kB
str(api_result)를 해보면 다양한 객체들이 있는데, 결과값은 content에 적재된단다. 개발 가이드의 R 코드 예시 참고.
# 결과 조회
api_result$content
그런데 결과는 아래와 같이 raw형식으로 알아볼 수가 없다.
[1] 7b 22 53 74 61 74 69 73 74 69 63 53 65 61 72 63 68 22 3a 7b 22 6c 69 73 74 5f 74 6f 74 61
[31] 6c 5f 63 6f 75 6e 74 22 3a 32 36 2c 22 72 6f 77 22 3a 5b 7b 22 53 54 41 54 5f 43 4f 44 45
[61] 22 3a 22 38 31 37 59 30 30 32 22 2c 22 53 54 41 54 5f 4e 41 4d 45 22 3a 22 31 2e 33 2e 32
[91] 2e 31 2e 20 ec 8b 9c ec 9e a5 ea b8 88 eb a6 ac 28 ec 9d bc eb b3 84 29 22 2c 22 49 54 45
< 중 략 >
[ reached getOption("max.print") -- omitted 6679 entries ]
예전 네이버 블로그 API 때도 그랬지만, 이를 살펴보기 위해서는 rawToChar() 함수를 이용해서 raw 형식을 문자로 변환하고, Encoding() 함수로 UTF-8로 인코딩까지 해야 결과를 정상적으로 한글로 조회할 수 있다고
# 문자로 변환?
result = rawToChar(api_result$content)
# 인코딩 설정
Encoding(result) = "UTF-8"
그리고 result 객체를 조회해보면 아래와 같이 조회된다.
이제 이 결과를 jsonlite 패키지의 fromJSON() 함수로 파싱하고, 데이터프레임으로 적재한다.
# json 파싱
result_json_parsing = fromJSON(result)
# 결과를 데이터프레임으로 적재
output_dataframe <- as.data.frame(result_json_parsing)
output_dataframe 객체를 조회해보면 개발명세서의 출력값이 모두 들어 있다. 필요 없는 항목들이 있으니 통계항목코드, 일자, 통계값에 해당하는 항목만 인덱싱하고, 데이터프레임의 컬럼명도 바꿔준다.
# 필요한 컬럼만 인덱싱
summary = output_dataframe[, c(5,13,14)]
# 컬럼명 변경
colnames(summary) = c("구분","기준일자","지표값")
그리고 조회를 하면 아래와 같이 일자별 데이터를 조회할 수 있고,
구분 기준일자 지표값
1 국고채(1년) 20230102 3.769
2 국고채(1년) 20230103 3.705
3 국고채(1년) 20230104 3.669
4 국고채(1년) 20230105 3.649
5 국고채(1년) 20230106 3.607
6 국고채(1년) 20230109 3.583
7 국고채(1년) 20230110 3.588
8 국고채(1년) 20230111 3.571
9 국고채(1년) 20230112 3.596
10 국고채(1년) 20230113 3.554
11 국고채(1년) 20230116 3.599
12 국고채(1년) 20230117 3.605
13 국고채(1년) 20230118 3.572
14 국고채(1년) 20230119 3.532
15 국고채(1년) 20230120 3.548
16 국고채(1년) 20230125 3.535
17 국고채(1년) 20230126 3.531
18 국고채(1년) 20230127 3.506
19 국고채(1년) 20230130 3.472
< 중 략 >
특정일자의 데이터만 조회하고 싶으면 아래와 같이 sqldf 패키지를 이용하면 된다. 물론 다른 방법들도 많이 있음
sqldf("
select 기준일자, 지표값
from summary
where 기준일자 in ('20230531','20230630','20230703')
"
)
원하는대로 코드 한번 짜놓으면 날짜만 바꿔가며 계속 활용할 수 있긴 한데, 여전히 이걸 사내 업무망이나 통계망에서 직접 하지 못한다는 것은 아쉽다. 뭐 더 좋은 방법이 없을까..
정보시스템 쪽에도 문의드려봐야지