build my life

[Python] Open API 실습 - ② 공공데이터포털 본문

실습

[Python] Open API 실습 - ② 공공데이터포털

dalovee 2022. 8. 23. 18:36
728x90
  • API 환경 또는 호출 조건에 따라 인증키가 적용되는 방식이 다름
  • 공공데이터 포털 같은 경우 일반 인증키가 encoding/decoding 방식으로 제공하고 있음
    -> 구동되는 키를 선택해서 사용하면 됨
  • 미리 요청주소와 인증키를 복사해두고 요청변수와 출력 결과 파라미터들을 확인함

출처 : 공공데이터포털

# 출처 : 공공데이터포털
# Python3 샘플 코드 #


import requests

url = 'http://apis.data.go.kr/B553734/iseelectricprod/getElectricProduction'
params ={
	'serviceKey' : '서비스키',
	'returnType' : 'xml/json',
	'numOfRows' : '10',
	'pageNo' : '1',
	'startDate' : '2016-01',
	'endDate' : '2019-12'
}

response = requests.get(url, params=params)
print(response.content)

 

1. 인증키와 요청변수들을 설정

service_key = "인증키"
return_type = "xml"
startdate = "2022-01"
enddate = "2022-01"

2. 요청주소 URL과 query 작성

url = "http://apis.data.go.kr/B553734/iseelectricprod/getElectricProduction"
query = f"?ServiceKey={ServiceKey}&returnType={return_type}&startDate={startdate}&endDate={enddate}"

> 공공데이터포털에서 제공해준 샘플코드로 하면 더 쉽겠지만 위의 방식으로 하기 전에 어떤 식으로 데이터가 요청이 되는지 확인하고자 url 뒤에 query를 연결하는 것으로 접근했다.

> URL 구조를 보면 query부분을 통해 데이터가 요청된다!

 

3. requests 라이브러리의 get 메소드를 활용해 요청 객체 생성

res = re.get(url + query)
res.status_code

 

4. res.text를 확인해보니 에러가 있는 것으로 확인!

> URL에서 사용할 수 없는 한글이나 특수문자들을 인코딩해주는 작업이 필요하다.

<OpenAPI_ServiceResponse> <cmmMsgHeader> <errMsg>SERVICE ERROR</errMsg> <returnAuthMsg>SERVICE_KEY_IS_NOT_REGISTERED_ERROR</returnAuthMsg> <returnReasonCode>30</returnReasonCode> </cmmMsgHeader> </OpenAPI_ServiceResponse>

 

URL 인코딩

  • 퍼센트(%) 인코딩이라고도 함
  • 영문자와 숫자와 일부 특수문자를 제외한 URL에서 사용할 수 없는 문자들을 인코딩 해주는 작업
service_key = "인증키"
service_key = re.utils.quote(service_key)

> 공공데이터포털은 인코딩된 키도 제공하니 따로 인코딩할 필요 없이 가져다가 쓰면 된다!

 

결과) 아래와 같이 html 응답을 잘 받아온 것을 확인할 수 있다.

<?xml version="1.0" encoding="UTF-8"?>
\n<response><header><resultCode>00</resultCode>
<description>서울에너지공사 발전소 월별 전기생산량(발전량)</description>
<resultMsg>NORMAL CODE</resultMsg></header><body><pageNo>1</pageNo>
<totalCount>2</totalCount><items><item><unit>kWh</unit>
<elecprodqty>12911900.00</elecprodqty><dates>2022-01</dates>
<branchNm>동부지사</branchNm><branchCd>2</branchCd></item>
<item><unit>kWh</unit><elecprodqty>8964872.00</elecprodqty>
<dates>2022-01</dates><branchNm>서부지사</branchNm>
<branchCd>1</branchCd></item></items><numOfRows>10</numOfRows></body></response>

 

하지만, 좀 더 보기 쉽게 변환해보자.

 

1. xmltodict 패키지 설치

!pip install xmltodict

2. 딕셔너리 형태로 변환

import xmltodict as xtd
dict_data = xtd.parse(res.text)

#output
{'response': {'header': {'resultCode': '00',
   'description': '서울에너지공사 발전소 월별 전기생산량(발전량)',
   'resultMsg': 'NORMAL CODE'},
  'body': {'pageNo': '1',
   'totalCount': '2',
   'items': {'item': [{'unit': 'kWh',
      'elecprodqty': '12911900.00',
      'dates': '2022-01',
      'branchNm': '동부지사',
      'branchCd': '2'},
     {'unit': 'kWh',
      'elecprodqty': '8964872.00',
      'dates': '2022-01',
      'branchNm': '서부지사',
      'branchCd': '1'}]},
   'numOfRows': '10'}}}

 

3. pprint 사용하여 좀 더 보기 쉽게 정리

import pprint as pp
pp.pprint(dict_data)

#output
{'response': {'body': {'items': {'item': [{'branchCd': '2',
                                           'branchNm': '동부지사',
                                           'dates': '2022-01',
                                           'elecprodqty': '12911900.00',
                                           'unit': 'kWh'},
                                          {'branchCd': '1',
                                           'branchNm': '서부지사',
                                           'dates': '2022-01',
                                           'elecprodqty': '8964872.00',
                                           'unit': 'kWh'}]},
                       'numOfRows': '10',
                       'pageNo': '1',
                       'totalCount': '2'},
              'header': {'description': '서울에너지공사 발전소 월별 전기생산량(발전량)',
                         'resultCode': '00',
                         'resultMsg': 'NORMAL CODE'}}}

 

728x90