3 분 소요

데이터 준비

취미로 하는 분석에서 기상 데이터가 필요해졌다. 그래서 농업기상 관측데이터를 가져오기로 했다.

encodingKey

사이트에 들어가서 활용신청을 누르고, encodingKey를 얻었다. 프로젝트 디렉토리에 잘 저장을 해두고, 다음과 같이 불러온다.

import requests
from xml.etree import ElementTree
import pandas as pd


# get key
encodingKey = ''
decodingKey = ''
with open("./personal/weather.txt", "r") as f:
            encodingKey = f.readline()
            decodingKey = f.readline()
encodingKey = encodingKey.replace('\n', '')

url 생성

이제 필요한 정보를 가져오기위한 url을 생성해야 한다. 정해진 양식에 맞춰서 url링크를 준비한다.

def mk_page_url(yr, mon, page, size=100):
    # make url
    url = 'http://apis.data.go.kr/1390802/AgriWeather/WeatherObsrInfo/GnrlWeather/getWeatherMonDayList'
    this_mon = str(mon) if mon >= 10 else ('0'+str(mon))
    queryParams = '?serviceKey=' + encodingKey + \
                '&Page_No=' + str(page) + \
                '&Page_Size=' + str(size) +\
                '&search_Year=' + str(yr) + \
                '&search_Month=' + this_mon
    return url + queryParams

XML 파싱

API를 통해 받아오는 결과는 xml형식이다. 그래서 이것을 파싱해서 원하는 값만 들고온 후, 작업하기 편한 DataFrame으로 만들었다.

# get monthly 
def get_monthly_weather_once(myurl):
    response = requests.get(myurl)
    root = ElementTree.fromstring(response.content)

    if root[0][0].text == '200':
        this_df = pd.DataFrame()
        for body in root.iter('body'):
            for items in body.iter('items'):
                for item in items.iter('item'):
                    tmp_dict = {}
                    for i in item:
                        tmp_dict[i.tag] = i.text
                    
                    tmp_df = pd.DataFrame.from_records([tmp_dict])
                    this_df = this_df.append(pd.DataFrame(tmp_df))
        return this_df
    else:
    	print("\n")
        print(root[0][0].text)
        print("에러 코드를 확인하세요!")

필요 데이터 받아오기

지금까지 만든 함수들을 조합해서 특정 ‘년월’에 해당하는 데이터 전체를 받아오는 함수를 만들었다.

def get_monthly_weather(year, mon):
    print(year,"년 ",mon,"월 데이터 수집 시작 >>> ", end='')
    cond = True
    start_num = 1
    my_df = pd.DataFrame()
    while cond:
        try:
            full_url = mk_page_url(year, mon, start_num)
            tmp_df = get_monthly_weather_once(full_url)
            my_df = my_df.append(tmp_df)
            cond = len(tmp_df)
            start_num += 1
        except:
            print(start_num,"번 페이지에서 에러나서 종료:( \n")
            break
    print("수집 끝!!")
    return my_df

저장

이제 실제로 데이터를 받아와서 한 번에 저장해보자. 운영계정을 받으면 한 번에 필요한 대용량 데이터를 모두 내릴 수 있다.

# 학습 전체기간 저장
for y in range(2016,2021):
    for m in range(1,13):
        weather_df = get_monthly_weather(y, m)
        weather_df = weather_df.drop_duplicates()
        weather_df.to_csv(f'./data/weather/weather_{y}_{m}.csv', encoding='cp949')