컴공돌이의 취미 블로그

[1]. 지방재정 365 OpenAPI 사용 방법 - (2) 본문

Study/OpenAPI

[1]. 지방재정 365 OpenAPI 사용 방법 - (2)

컴공돌이​​ 2017. 7. 20. 14:24

[1]. 지방재정 365 OpenAPI 사용 방법 - (2)


오늘은 지난번에 작성한 지방재정 365 의 OpenAPI 의 사용법중에서도 실질적으로 사용하는 코드에 대한 글을 작성해보고자 한다.


이전 글의 순서대로 진행을 하면 지방재정 365의 OpenAPI 에 접근할 수 있는 Url을 받을 수 있을 것이고 또한 인증키 발급과 사용법도 알 수 있을 것이다.


이제 OpenAPI를 사용하여 데이터를 가져오는 코드를 분석해 보자.


<코드 분석>

(1). XML 패키지의 설치와 호출

1
2
install.packages("XML")
library(XML)
cs

이전 글에서 살펴보면 OpenAPI를 통해서 가져올수 있는 데이터의 형태는 xml 혹은 json 이다.

이번글에서는 xml파일의 형태로 데이터를 가져올 것이기 때문에, 데이터를 다루기 위해서 xml 패키지를 설치하고 호출하여 사용할 것이다.


(2). RCurl 패키지의 설치와 호출

1
2
install.packages("RCurl")
library(RCurl)
cs

코드의 중간에 페이지의 형태를 읽어들이는 함수 getForm() 이라는 함수가 있다.

이 함수는 RCurl의 패키지 안에 저장되어져 있는 함수이기 때문에 이를 사용하기 위해서 RCurl 패키지를 설치하고 호출한다.


(3). 요청주소의 인자들

1
2
3
4
5
6
7
url1 <- "http://lofin.moi.go.kr/HUB/"
category <- "GJSCS"
url2 <- "?type="
datatype <= "xml"
url3 <- "&key="
mykey <- "oooooooooo"
url4 <- "&accnut_year="
cs

OpenAPI에 접근할 Url을 구성하는 인자들이다.

url이라고 써져있는 인자들은 수정하면 안되는 인자들이고, category, datatype, mykey는 수정이 가능한 인자이다.

category는 어떠한 분야의 데이터를 가져오고 싶은지 지방재정 홈페이지에서 확인 후 원하는 코드를 적으면 된다.

datatype는 xml 혹은 json의 둘중 1개를 선택하여 적으면 되지만 이글에서는 xml으로 사용하였다.

mykey는 지방재정에서 발급받은 인증키를 복사하여 붙여넣기 하면 된다.

위의 인자들에서 원하는 년도만 집어넣으면 기본적인 요청주소가 완성된다.


(4). 데이터를 저장할 데이터프레임 선언

1
table <- data.frame()
cs

OpenAPI를 통해서 읽어들인 데이터를 저장하기위해서 데이터 프레임을 선언해 준다.


(5). 모든 년도의 데이터를 구하기 위해서 반복문을 사용하여 요청 주소를 설정하기

1
2
3
4
5
6
7
8
9
for(year in 2000:2017){
  requestUrl <- paste(url1, category, url2, datatype, url3 ,mykey, url4, year, sep="")
  try(
    {
      ......
    }, silent = TRUE
  )
}
 
cs
직접 알아본 결과 지방재정 365에서의 데이터들 중에서 가장 오래된 데이터는 2000년도 데이터인것 같아서 2000년 부터 제일 최근의 데이터인 2017년 데이터를 얻기 위하여 반복문을 사용해주었다.

requestUrl에 앞에서 적은 요청주소 인자들과 반복문에서 사용된 년도 값을 합쳐서 기본적인 요청주소를 완성한다.

또한 try 문법을 사용하여 안에서 오류가 날 경우 예외처리를 해주기로 하였다.

(6). try 내부 코드 1 - 페이지 번호 구하기

1
2
3
4
page = getForm(requestUrl, query="")
doc = xmlToDataFrame(page)
totalPageNumber <- doc[1,1]
totalPageNumber <- as.numeric(totalPageNumber)%/%100
cs

OpenAPI를 사용해서 접근한 페이지에는 데이터의 양이 한정되어 있다.

따라서 위에서 만든 기본적인 요청주소 뒤에 페이지의 번호를 붙여서 완벽한 요청주소를 만들어야한다.

기본 요청주소를 통하여 접근한 페이지를 보면 전체 데이터의 수가 나와 있다.

이때 우리는 한 페이지에 보이는 데이터 수를 설정하지 않았기에 기본값으로 100으로 되어 있어, 한 페이지에는 100개의 데이터가 나와있다.

따라서 이를 나누어서 전체 페이지 갯수를 구할수 있는 것이다.


(7). try 내부 코드 2 - 모든 페이지의 데이터를 하나의 테이블에 저장하기

1
2
3
4
5
6
7
8
9
10
for(pageNumber in 1:(totalPageNumber+1)){
  Url <- paste(requestUrl, "&pIndex=", pageNumber, sep="")
  page = getForm(Url, query="")
  doc = xmlToDataFrame(page)
  if(length(table)==0){
    table <- doc[-c(1),-c(1,2)]
  }
  else{
    table <- rbind(table, doc[-c(1), -c(1,2)])
  }
cs

위에서 구한 페이지넘버마다 반복문을 실행하여 완벽한 요청주소를 생성한다.

생성한 요청주소를 통해서 접근하여 getForm 함수로 페이지를 읽어들인 후 xmlToDataFrame함수를 사용하여 데이터프레임의 형태로 변환시킨다.

그리고 table을 검사하여 비어있는 경우는 현재 읽어들인 페이지의 데이터를 테이블에 저장하고 만약 비어있지 않은 경우에는 데이터를 table에 이어서 붙인다.


<전체 코드>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
// xml 형식의 데이터를 다루기 위해서 패키지를  다운 후 호출
install.packages("XML")
library(XML)
 
// 특정 함수를 사용하기 위해서 패키지를 다운 후 호출
install.packages("RCurl")
library(RCurl)
 
//////요청주소 요소들
//// 바꿀 필요 없는 부분
url1 <- "http://lofin.moi.go.kr/HUB/"
url2 <- "?type="
url3 <- "&key="
url4 <- "&accnut_year="
 
////원하는 값을 입력하는 부분
// 데이터를 가져올 카테고리 명
category <- "GJSCS"
// 원하는 데이터 타입
datatype <= "xml"
//발급받은 인증키
mykey <- "oooooooooo"
 
//데이터를 저장할 데이터프레임을 선언
table <- data.frame()
 
//2000년도 부터 2017년도 까지의 데이터를 모두 받기 위해서 반복문 사용
for(year in 2000:2017){
  // 위에 설정해놓은 요청주소에 필요한 모든것을 이어붙여서 요청주소를 생성
  requestUrl <- paste(url1, category, url2, datatype, url3 ,mykey, url4, year, sep="")
  try(
    {
      //요청주소에 접근하여 데이터를 읽어들임
      page = getForm(requestUrl, query="")
      //xml형식의 파일을 Data frame의 형태로 변환하여 저장
      doc = xmlToDataFrame(page)
      //데이터가 있는 페이지 번호를 구하기 위해서 전체 데이터 개수를 구한 후 100으로 나눔
      totalPageNumber <- doc[1,1]
      totalPageNumber <- as.numeric(totalPageNumber)%/%100
      //1번째 페이지부터 마지막 페이지까지 반복문을 실행
      for(pageNumber in 1:(totalPageNumber+1)){
        // 요청주소 뒤에 페이지 번호를 붙여 완벽한 주소를 생성
        Url <- paste(requestUrl, "&pIndex=", pageNumber, sep="")
        // 주소로 부터 데이터를 읽어 들임
        page = getForm(Url, query="")
        //xml 형식의 파일들을 Data frame의 형태로 변환하여 저장
        doc = xmlToDataFrame(page)
        // table이 비어있는지를 확인
        if(length(table)==0){
          //비어있다면 현재 페이지의 데이터를 테이블에 저장
          table <- doc[-c(1),-c(1,2)]
        }
        else{
          //비어있지 않다면 현재 테이블의 데이터를 기존 table의 뒤에 이어서 붙임
          table <- rbind(table, doc[-c(1), -c(1,2)])
        }
      }
    },
    silent = TRUE
  )
}
cs



<코드 실행 시 얻는 데이터>


반응형