사용 라이브러리 포함
from urllib.request import urlopen
from urllib.parse import urlencode, unquote, quote_plus
import urllib
import json
import pandas as pd
import time
import datetime
이하 API 코드
#조회할 첫 날짜 년,월,일,시,분,초
first_date = datetime.datetime(2011,1,1,0,0,0)
#조회할 마지막 날짜, 본 코드는 현 시간에서 하루를 뺀 일자를 입력했습니다. (사용한 API에서는 당일 하루 전 데이터까지만 제공하기때문)
last_date = datetime.datetime.now() - datetime.timedelta(days=1)
#지역 번호(지점번호) 지정
point = 165
now = first_date
#1년 후 날짜 계산
now_after_365 = now + datetime.timedelta(days=365)
#공공데이터 서비스 키 입력
servicec_key = "서비스키"
url = 'http://apis.data.go.kr/1360000/AsosHourlyInfoService/getWthrDataList'
#매년 데이터를 누적할 LIST 초기화
get_list = []
#마지막 년도가 증감 년도보다 작거나 같으면 루프 종료
while not last_date.year <= now.year:
i = 1 #페이지 수 변수 초기화
#마지막 일자일 경우 변수 지정
if last_date.year == now.year+1:
now_after_365 = last_date
print(now.strftime("%Y%m%d"),now_after_365.strftime("%Y%m%d"))
#페이지 루프
while True:
#API에 요청할 파라미터 정의
params = '?'+urlencode({'serviceKey' : servicec_key,
'pageNo' : i,
'numOfRows' : '999', #최대 999개까지 가능
'dataType' : 'JSON',
'dataCd' : 'ASOS',
'dateCd' : 'HR',
'startDt' : now.strftime("%Y%m%d"),
'startHh' : '01',
'endDt' : now_after_365.strftime("%Y%m%d"),
'endHh' : '01',
'stnIds' : point
})
#API 요청
req = urllib.request.Request(url + unquote(params))
#받아온 Response 데이터 읽기
response_body = urlopen(req, timeout=60).read()
#json 데이터로 읽기
data = json.loads(response_body)
#페이지에서 데이터가 없으면 break
if data['response']['header']['resultMsg'] == "NO_DATA":
break
try:
print("데이터 회신 성공",data['response']['header']['resultMsg'])
get_list = get_list+ data['response']['body']['items']['item']
print(len(get_list))
except:
print(data['response']['header']['resultMsg'])
print("가져오기 실패 ----> 5초 기다린 후 재시도")
time.sleep(5)
req = urllib.request.Request(url + unquote(params))
response_body = urlopen(req, timeout=60).read()
data = json.loads(response_body)
get_list = get_list+ data['response']['body']['items']['item']
print(data)
i = i+1
#현 날자를 이전 마지막 날자 다음날로 설정
now = now_after_365 + datetime.timedelta(days=1)
#마지막날을 현 날자 1년뒤로 설정
now_after_365 = now + datetime.timedelta(days=365)
print("----> 5초 기다림")
time.sleep(5)
#리스트 dataframe으로 변환
df = pd.DataFrame(get_list)
#데이터프레임 csv로 저장
df.to_csv('weather_'+str(point)+'_'+first_date.year+'_'+last_date.year+'.csv',encoding='utf-8-sig')
print(df)
+ 본 API에 너무 자주 데이터 요청을 하게 되면 잠시 거부 상태가 될 수 있기 때문에 Sleep을 한번씩 걸어줘야 합니다.
+ API에서 제공하는 날짜 범위 내, 지점 범위 내에 있는 데이터 변수만 사용하여야 에러 발생을 방지할 수 있습니다.