Python/Crawling

[Python - Crawling] API 활용하여 과거 기상 관측 데이터 불러오기

슈퍼짱짱 2023. 3. 28. 10:05
반응형

기상청 허브에서 제공하는 API를 활용하여 파이썬으로 과거 기상 관측 데이터를 불러와 보겠다.

본 포스팅에서는 1. 먼저 기상청 API 허브 사이트에 대해 설명하고, 2. 파이썬 코드로 실제 불러오는 부분을 실습해보겠다.

 


먼저 기상청 API 허브 사이트에서 회원가입을 한다.

https://apihub.kma.go.kr/

 

기상청 API허브

 

apihub.kma.go.kr

 

회원가입, 로그인을 하고나면 마이페이지에 자동으로 인증키가 생성된다. 따로 신청할 필요도 없다.

 

마이페이지

 

위 사진과 같이 개인 회원은 하루 최대 2,000건 호출 할 수있으며, 현재 몇 회 호출했는지도 확인할 수 있다.

(기업 회원은 하루 최대 3,000건)

 


과거 지상에서 관측되었던 날씨를 불러오고 싶다면 홈페이지에서 "지상관측"을 눌러 들어간다.

 

지상관측 클릭

 

지상 정보 외에도 해양, 고층 등 다양한 정보를 얻을 수 있다. 과거 관측정보 외에 예특보 정보도 얻을 수 있으니 다양하게 활용할 수 있다.

본 포스팅에서는 지상관측으로 실습을 진행하겠다.

 


 

지상관측

 

지상관측 중에서도 다양한 관측 정보가 존재한다. 

각 탭을 눌러보면 어떤값인지 설명도 잘 써있다.

 

종관기상관측(ASOS)로 진행하겠다.

 


 

지상 관측자료 조회

 

시간대별 관측자료, 일별 관측자료 등 원하는 부분을 얻어오면 된다.

시간자료는 1시간 단위 관측 정보이며, 일자료는 하루 단위(일평균) 관측 정보이다.

 

각 자료별 바로 아래 url 중 "?" 바로 직전(.php)까지가 기본 url이고 뒤에 tm~ 부터 붙어있는건 조회 예시이다.

 

시간자료(기간조회)를 눌러보면 다음과 같다.

tm1에 201512110100, tm2에 201512140000, stn에 108, help에 1, 마지막으로 인증키를 파라미터로 입력해서 API를 요청하면 다음과 같은 결과를 return해주겠다는 예시이다.

 

컬럼 Description
결과 예시

 

위에 이미지는 각 컬럼에 대한 설명이고, 아래 이미지는 결과 예시이다.

 

tm1, tm2와 같은 input parameter 역시 사이트에 잘 설명되어 있다.

 

요청인자

 

출력 결과 각 컬럼에 대한 설명도 있다.

시간자료와 일자료에서 return하는 결과가 다르고, 아래 테이블은 모든 컬럼에 대한 설명을 담고있다.

각 자료에 대한 컬럼 정보는 위에 각 url을 클릭해보면 된다.

 

 

 

 


이제 파이썬으로 해당 API를 호출하여 과거 한 시간 단위 지상 관측 날씨 정보를 불러와 보겠다.

 

먼저 필요한 라이브러리를 호출한다.

 

import pandas as pd
import requests
from datetime import datetime,timedelta

import warnings
warnings.filterwarnings('ignore')

 

start time과 end time을 입력하면 해당하는 시간의 날씨를 불러오는 function은 다음과 같다.

 

col_name =["TM",     "STN",    "WD",     "WS",     "GST_WD", "GST_WS", "GST_TM", "PA",     "PS",     "PT",     "PR",     "TA",     "TD",     "HM",     "PV",     "RN",     "RN_DAY", "RN_JUN", "RN_INT", "SD_HR3", "SD_DAY", "SD_TOT", "WC",     "WP",     "WW",     "CA_TOT", "CA_MID", "CH_MIN", "CT",     "CT_TOP", "CT_MID", "CT_LOW", "VS",     "SS",     "SI",     "ST_GD",  "TS",     "TE_005", "TE_01",  "TE_02",  "TE_03",  "ST_SEA", "WH",     "BF",     "IR",     "IX"]
def weather(tm1, tm2) :
    url = 'https://apihub.kma.go.kr/api/typ01/url/kma_sfctm3.php'
    key = "본인 인증키를 입력하세요"
    params ={'tm1' : tm1, 
             'tm2' : tm2, 
             'stn' : 152,
             'help' : 0, 
             'authKey' : key}

    response = requests.get(url, params=params, verify=False)

    text = response.text
    text = text.split("\n")[4:-2]
    
    df = pd.DataFrame(text)[0].str.split(expand=True)
    df.columns = col_name
    return df

 

실행 예시

 

col_name은 컬럼명으로, 컬럼 Description을 그대로 가져왔다.

요청할 url은 위에서 언급했듯, 호출 URL 정보에서 "?" 직전까지이다.

 

예를 들어, 호출 URL이 다음과 같이 되어있었다면,
https://apihub.kma.go.kr/api/typ01/url/kma_sfctm3.php?tm1=201512110100&tm2=201512140000&stn=108&help=1&authKey=인증키비밀 

 

"?" 앞에있는 https://apihub.kma.go.kr/api/typ01/url/kma_sfctm3.php 까지가 요청할 url이며, 뒤에는 parameter로 전달할 요청인자이다.

 

"tm"은 년월일시분을 이어서 쓴다.

예로 2023-03-28 8시는 202303280800으로 쓰면된다.

 

"stn"은 국내 지점번호로, 서울/부산/울산 등 지역을 의미한다.

위 코드는 지점번호가 152인 "울산" 지역에 대한 날씨를 불러오는 코드이다.

만약 전체 지역을 모두 불러오고싶다면 그냥 'stn' = '' 로 전달하면 된다. 전체 97개 지점에 대한 날씨정보가 모두 return된다.

 


 

각 stn 지점 번호가 의미하는 지역은 지상관측에서 가장 마지막 텝인 "지상관측 지점정보"를 클릭해 마찬가지로 API를 호출하면 알 수 있다.

 

 

지점정보를 불러오는 코드는 다음과 같다.

 

url = "https://apihub.kma.go.kr/api/typ01/url/stn_inf.php"
params ={'inf' : 'SFC',
         'stn' : '',
         'authKey' : '인증키를 입력하세요'}

response = requests.get(url, params=params, verify=False)

text = response.text
text = text.replace("#","").split("\n")

text = text[1:-2]
for i,l in enumerate(text):
    l = l.strip().replace(" ",",").split(',')
    l = [i for i in l if i != '']
    l = ",".join(l)
    text[i] = l
    
# column name setting
col_name1 =  text[0].split(',')
col_name2 = text[1].split(',')
col_name2 = [i.replace("-","") for i in col_name2]
col_name = [n1+"("+n2+")" for n1,n2 in zip(col_name1,col_name2)]
col_name = [c.replace("()","") for c in col_name]

df_temp = pd.DataFrame(text[2:])[0].str.split(",", expand=True)

df_temp = df_temp.drop(14, axis = 1)
df_temp.columns = col_name

 

이는 처음에 딱 한번만 불러오고 따로 파일로 저장하면 쭉 활용할 수 있다.

df_temp 결과를 csv로 저장한 파일도 함께 첨부하겠다.

 

KMA_ASOS_observation_location_info.csv
0.01MB

 

 

STN 지점번호 API 호출 결과

 


 

참고로 한 번 호출하면 tm2(end time)부터 최대 720시간 앞 까지만 불러올 수 있다.

720시간보다 더 긴 시간을 호출하고싶다면 끊어서 여러번 불러와야한다.

 

예로 위에서 구현한 weather function을 활용하여 2020-01-01 부터 2023-03-27까지 울산지역 지상 관측 날씨를 불러오는 코드는 다음과 같다.

 

dates = pd.date_range('2020-01-01','2023-03-27', freq = 'H')
dates = [str(d).replace("-","").replace(" ","").replace(":","")[:-2] for d in dates]

df_all = pd.DataFrame()
d_i = 0
while d_i <= len(dates) : 
    start_time = dates[d_i]    
    if d_i+719 >= len(dates):
        end_time = dates[-1]
    else:
        end_time = dates[d_i+719]
    d_i += 720
#     print(d_i, start_time, end_time)
    
    df = weather(start_time, end_time)
    df_all = pd.concat([df_all, df])

 


 

* 과거 데이터를 분석할 때는 이렇게 예보가 아닌 관측 데이터를 사용하면 더 정확하다. 하지만, 해당 데이터로는 미래를 예측할 수는 없으므로 날씨 정보를 활용하여 무언가를 예측하고 싶다면 예보 데이터를 활용해야 한다. *

 


출처

내 영혼의 단짝 MJ..❤️

반응형