본문 바로가기
공부/데이터

[python] 공공데이터 API호출 및 pandas 로 변환하기

by demonic_ 2019. 11. 3.
반응형

공공데이터 홈페이지

https://www.data.go.kr/

 

공공데이터포털

국가에서 보유하고 있는 다양한 데이터를『공공데이터의 제공 및 이용 활성화에 관한 법률(제11956호)』에 따라 개방하여 국민들이 보다 쉽고 용이하게 공유•활용할 수 있도록 공공데이터(Dataset)와 Open API로 제공하는 사이트입니다.

www.data.go.kr

 

'상권정보'로 검색하면 다음과 같은 결과가 나온다.

 

 

각각 데이터를 제공하는 방식이 다른데, 위의 파일데이터는 csv나 xls 등 파일로 제공한다는 것이고, 아래가 API를 이용해 호출하는 것이다. 이번 글은 API에 관련된 것이니 아래것을 참조한다.

 

End Point는 도메인의 root 경로다. 해당 API의 모든 경로는 저 경로에서 시작한다고 보면 된다.

데이터포멧은 JSON 또는 XML 로 제공한다는 의미다. JSON과 XML의 차이점은 아래 추가했다.

참고문서는 어떻게 활용하고 호출할 수 있을지 상세히 설명되어 있다.

End Point 에 써있는 경로를 브라우저로 호출하면 다음과 같은 에러가 발생한다.

 

정책위조라고 나오는데, End Point는 경로일 뿐이고 실제 데이터를 호출하는 것은 URL 이 좀더 추가되어야 한다. 자세한 사항을 살펴보기 위해 참고문서를 열어본다.

참고문서를 다운받아 열어보면 인증키를 활용하는 방법과 서비스별로 어떻게 활용하면 좋을지 알려준다.

 

위의 경로를 보면 End Point 이후 오퍼레이션 명, 필수항목 등을 입력하게 되어있고, ServiceKey를 같이 넣어주어야 한다고 써있다.

오퍼레이션 분류는 문서에서 상세히 설명되어 있다. API 중에는 오퍼레이션명이 없는 경우도 있으니 문서는 항상 참고해야한다.

 

서비스키는 API활용 신청을 하면 마이페이지에서 확인할 수 있다.

신청페이지는 API 설명이 있는 화면에서 활용신청을 클릭하면 된다. 요즘은 거의 즉시 허가가 나는 듯 하다.

아래 일반 인증키 에 써있는 것이 ServiceKey다.

 

문서에 써있는 샘플 호출에 서비스키를 추가하여 브라우저로 호출해보면 다음과 같은 결과가 나온다.

데이터의 기본 포멧은 XML이다.

호출 URL

http://apis.data.go.kr/B553077/api/open/sdsc/storeZoneOne?key=573&ServiceKey=[서비스키(일반 인증키)]

 

JSON으로 호출하려면 파라미터를 추가해주어야 한다.

API마다 json으로 변환하는 방법이 조금 다른데 살펴보는 상권 API는 브라우저 파라미터에 '&type=json'를 추가하면 된다.

관련된 내용도 문서에 포함되어 있다.

 

호출 URL(JSON 형태)

http://apis.data.go.kr/B553077/api/open/sdsc/storeZoneOne?key=573&ServiceKey=[서비스키]&type=json

 

 

그럼 이제부터 python으로 호출하여 padnas로 저장해보자

 

 

# Python을 이용해 API 호출하여 pandas로 변환하기

개인적으로 json을 선호하기 때문에 json으로 호출하였다.

import urllib.request

#-*- coding:utf-8 -*-
http://apis.data.go.kr/B553077/api/open/sdsc/storeZoneInRadius?radius=500&cx=127.004528&cy=37.567538&ServiceKey=[서비스키]&type=json

response = urllib.request.urlopen(url)

json_str = response.read().decode("utf-8")

 

인코딩을 utf-8로 전환하여 결과를 받는다.

json이라 하더라도 포멧팅이 그렇다는 것이지 실제로 json객체는 아니다.

그래서 type(json_str) 을 입력하면 str 로 나온다.

이제 json을 import 하여 문자열 -> json으로 변환한다

import json
json_object = json.loads(json_str)
json_object
{'header': {'description': '소상공인시장진흥공단 주요상권',
  'resultCode': '00',
  'resultMsg': 'NORMAL SERVICE'},
 'body': {'items': [{'trarNo': 2207,
    'mainTrarNm': '동대문역사문화공원역',
    'ctprvnCd': '11',
    'ctprvnNm': '서울특별시',
    'signguCd': '11140',
    'signguNm': '중구',
    'trarArea': 81499.1,
    'coordNum': 8,
    'coords': 'POLYGON ((127.007565 37.565945, 127.004846 37.566394, 127.002877 37.566759, 127.002341 37.566737, 127.00252 37.5647, 127.004682 37.564852, 127.007062 37.564448, 127.007565 37.565945))',
    'stdrDt': '2015-12-17'},
   {'trarNo': 2214,
    'mainTrarNm': '을지로4가역',
    'ctprvnCd': '11',
    'ctprvnNm': '서울특별시',
    'signguCd': '11140',
    'signguNm': '중구',
    'trarArea': 88434.9,
    'coordNum': 8,
    'coords': 'POLYGON ((126.999081 37.566789, 127.002102 37.566937, 127.001981 37.568644, 127.001871 37.568655, 127.001873 37.569521, 126.998065 37.568812, 126.998213 37.566753, 126.999081 37.566789))',
    'stdrDt': '2015-12-17'},
   {'trarNo': 2216,
...

 

데이터를 보면 header와 body가 나뉜다. 우리가 필요한 정보는 body이니 그쪽 정보를 로드해서 pandas로 변형되도록 해야한다.

API마다 내부 구조가 다를 수도 있다.(어떤 API는 header와 body의 구분 없이 list 키 아래 배열로 저장되 있는 경우도 있는 등 다양함)

pandas를 이용해 json을 pandas 형태로 바꾼다

import pandas as pd
from pandas.io.json import json_normalize

body = [json_object['body']['items']]
body
[[{'trarNo': 2207,
   'mainTrarNm': '동대문역사문화공원역',
   'ctprvnCd': '11',
   'ctprvnNm': '서울특별시',
   'signguCd': '11140',
   'signguNm': '중구',
   'trarArea': 81499.1,
   'coordNum': 8,
   'coords': 'POLYGON ((127.007565 37.565945, 127.004846 37.566394, 127.002877 37.566759, 127.002341 37.566737, 127.00252 37.5647, 127.004682 37.564852, 127.007062 37.564448, 127.007565 37.565945))',
   'stdrDt': '2015-12-17'},
  {'trarNo': 2214,
   'mainTrarNm': '을지로4가역',
   'ctprvnCd': '11',
   'ctprvnNm': '서울특별시',
   'signguCd': '11140',
   'signguNm': '중구',
json_normalize(json_object['body']['items'])

 

다음과 같이 pandas로 변형되었음을 확인할 수 있다.

끝.

 

반응형

댓글