본문 바로가기

프로그래밍/Python

[Python|OPENAPI] 기상청 기상관측 자료 OPENAPI requests 샘플코드

728x90

기상청에서 openapi 로 제공하는 자료를 openapi 를 이용하여, 받아서 활용할 수 있다. 보통 python 으로는 requests 모듈을 이용하여, requests.get(url, params=params) 형식으로 간단하게 가져와서 내용은 json으로 파싱하여 사용하는 것이 익숙한 방법이다.

그런데, 기상청에 회원가입하여 발급받은 apikeyrequests 에서 자동으로 url encoding 을 해 버리는 특수문자 %/ 이 포함되어 있었다. 그래서, 기본적인 방법으로는 500 에러가 발생하였으며, 약간의 꼼수 코드가 필요했다. 기상청 게시판을 보니까 비슷한 상황에 있는 사람들이 있는 것도 같아서, 내가 사용하여 성공한 코드를 포스팅한다.

사용한 코드 스니펫( 즉 아래의 noq_Session 함수 )은 구글링하여 찾은 stack overflow 질문/답변에 찾은 것이다.

아래코드는 기상청 제공 api 중에서 지상관측(종관) 시간자료를 요청한 것이다.


import requests
import json
import pandas as pd
from pprint import pprint
import urllib.parse
from urllib.request import urlopen


class noq_Session(requests.Session):
    # https://stackoverflow.com/questions/23496750/how-to-prevent-python-requests-from-percent-encoding-my-urls
    # subclassing is needed, bcs my api key includes special characters ( %, / ) and if urlencoded by standard requests.get
    # the server doesn't give me the data.
    def send(self, *a, **kw):
        a[0].url = a[0].url.replace(urllib.parse.quote('%'), '%')
        a[0].url = a[0].url.replace(urllib.parse.quote('/'), '/')
        return requests.Session.send(self, *a, **kw)


url = 'http://data.kma.go.kr/apiData/getData'
params = {
    "type":"json",
    "dataCd":"ASOS",
    "dateCd":"HR",
    "startDt":"20150101",
    "startHh":"00",
    "endDt":"20181231",
    "endHh":"23",
    "stnIds":"108", # 108 for Seoul
    "schListCnt":500,
    "pageIndex":1,
    "apiKey":"XXXXXXXXXXXXXXXXXXXXXXXXXXXX" # 여기에 회원가입/사용신청후 발급받은 자신의 apikey 를 넣는다. 나의 경우 특수문자가 포함되어 있었다.
}

s = noq_Session()
r = s.get(url, params=params, verify=False)
pprint(r)