-
실시간 날씨 예보를 CSV파일에 기록하고, 주기적으로 그래프 그리는 함수보고서 및 정보/파이썬, 머신러닝 2020. 8. 1. 22:14
from pandas import Series, DataFrame
import pandas as pd
import matplotlib as mpl
import re
import csv
# In[6]:
import threading
from bs4 import BeautifulSoup
import urllib.request as MyURL
import matplotlib.pyplot as plt
get_ipython().run_line_magic('matplotlib', 'inline')
font_name = mpl.font_manager.FontProperties(fname='C:/Windows/Fonts/malgun.ttf').get_name()
mpl.rc('font', family=font_name)
mpl.rcParams['axes.unicode_minus'] = False
WT = 'http://www.kma.go.kr/wid/queryDFSRSS.jsp?zone=4711370000'
response = MyURL.urlopen(WT)
weather = BeautifulSoup(response, "html.parser")
for pubdate in weather.find('pubdate'):
print("현재일시:",pubdate.string)
for title in weather.find('title'):
print("위치:",title.string)
#과거 데이터에 현재 및 미래 데이터 합산
def PastFuture():
time = []
temp = []
wind = []
day = []
timeall=[]
for data in weather.findAll('data'):
time_split = data.hour.string.split("/")
time = time + time_split
temp_split = data.temp.string.split("/")
temp = temp + temp_split
wind_split = data.ws.string.split("/")
wind = wind + wind_split
day_split = data.day.string.split("/")
day = day + day_split
str2 = re.findall("\d+",pubdate.string)
year = int(str2[0])
month = int(str2[1])
day_b = int(str2[2])
day_I = map(int,day)
Day_re = []
for i in day_I:
Day = str(i + day_b) + ' '
Day_re = Day_re + Day.split()
Day_I = map(int, Day_re)
Day_em = []
Day_om = []
month_om = []
month_em = []
month_e = []
year_om = []
year_em = []
for i in Day_I:
if ((i < 31) and (month == 4 or month == 6 or month == 9 or month == 11)):
Day = str(i) + ' '
Day_om = Day_om + Day.split()
month_om = month_om + list(str(month))
elif ((i >= 31) and (month == 4 or month == 6 or month == 9 or month == 11)):
Day = str(i - 30) + ' '
Day_em = Day_em + Day.split()
month_em = month_em + list(str(month+1))
elif ((i < 29) and (month == 2) and (year % 4 == 0)):
Day = str(i) + ' '
Day_om = Day_om + Day.split()
month_om = month_om + list(str(month))
elif ((i >= 29) and (month == 2) and (year % 4 == 0)):
Day = str(i - 28) + ' '
Day_em = Day_em + Day.split()
month_em = month_em + list(str(month+1))
elif ((i < 30) and (month == 2)):
Day = str(i) + ' '
Day_om = Day_om + Day.split()
month_om = month_om + list(str(month))
elif ((i >= 30) and (month == 2)):
Day = str(i - 29) + ' '
Day_em = Day_em + Day.split()
month_em = month_em + list(str(month+1))
elif (i < 32):
Day = str(i) + ' '
Day_om = Day_om + Day.split()
month_oms = str(month) + ' '
month_om = month_om + month_oms.split()
elif (i >= 32):
Day = str(i - 31) + ' '
Day_em = Day_em + Day.split()
month_ems = str(month+1) + ' '
month_em = month_em + month_ems.split()
month_pf = month_om + month_em
month_pfI = map(int,month_pf)
for i in month_pfI:
if i == 12:
Year = str(year) + ' '
year_om = year_om + Year.split()
elif i == 13:
month_e = month_e + list(str(i - 12))
month_pf = month_om + month_e
Year = str(year+1) + ' '
year_em = year_em + Year.split()
Day_pf = Day_om + Day_em
year_pf = year_om + year_em
year_s = ''
for i in range(len(Day_re)):
year_s = str2[0] + ' '
year_pf = year_pf + year_s.split()
DATE_ALL = ''
for i in range(len(day)):
DATE_ALL = DATE_ALL + year_pf[i] + '-' + month_pf[i] + '-' + Day_pf[i] + ' ' + time[i] + '.'
DATE_RE = DATE_ALL.split(".")
del DATE_RE[DATE_RE.index("")]
with open(r'C:/Users/해당 경로/PAST+FUTURE.csv', 'a', newline='') as csvfile:
fieldnames = ['시간','기온(°C)','풍속(m/s)']
writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
for i in range(len(day)):
writer.writerow({'시간':DATE_RE[i],'기온(°C)':temp[i],'풍속(m/s)':wind[i]})
PastFuture()
#3시간 간격으로 함수 실행
threading.Timer(10800,PastFuture).start()
# In[12]:
#중복항 제거 및 제거된 값으로 그래프 그리는 함수
def drop_plot():
df_forecast = pd.read_csv("C:/Users/해당 경로/PAST+FUTURE.csv",encoding='cp949')
df_re = df_forecast.drop_duplicates(['일시'])
df_re1 = df_re.set_index(['일시'])
df_re1.to_csv('C:/Users/해당 경로/PAST+FUTURE.csv',encoding='cp949')
ax3 = df_re1.plot(figsize=(12,4),legend=True, fontsize=12)
ax3.set_title(['과거 데이터 및 '+ pubdate.string+'시 기준 예보 데이터', title.string])
ax3.legend(['기온(°C)','풍속(m/s)'], fontsize=12)
ax3.set_ylabel("풍속(m/s), 기온(°C)")
ax3.set_xlabel("일시")
ax3.grid(True)
plt.tight_layout()
for label in ax3.xaxis.get_ticklabels() :
label.set_rotation(45)
drop_plot()
#3시간 간격으로 함수 실행
threading.Timer(10800,drop_plot).start()--------------------------------------------------------------------
기상청 http://www.kma.go.kr/wid/queryDFSRSS.jsp?zone=4711370000 에서 부터 정보를 다운로드 받아와 그것을 3시간 간격으로 csv파일에 자동 업로드해주며, 그래프를 최신화 해주는 코드입니다.
<순서>
1) 기상청(http://www.kma.go.kr/wid/queryDFSRSS.jsp?zone=4711370000)에서 예보데이터(3시간 간격, 2~3일치)를 얻어
원하는 데이터(날짜, 기온, 풍속)만 뽑아내는 코드 작성
2) 예보데이터 활용 시 날짜가 넘어가며 달이 바뀌고, 달이 넘어가며 년도가 바뀔 때 업데이트되지 않는 문제를 해결하고,
전 처리한 시간 데이터를 기상청 URL에서 뽑아낸 데이터와 합쳐 csv파일로 저장하는 함수 작성.
이때 기상자료개방포털(https://data.kma.go.kr/data/grnd/selectAsosRltmList.do?pgmNo=36)에서 받은 과거 데이터(1시간 간격)
위에 예보데이터(3시간 간격)를 쌓음.
3) 저장한 파일을 3시간 간격으로 업데이트 되게끔 함수를 자동 실행. 마찬가지로, 중복된 값을 없애주고 csv파일을 열어
그래프로 시각화하는 함수를 따로 만들고 이 함수 또한 3시간 간격으로 수행.
코드의 과거자료파일의 경우 위 2)항목의 url에서 다운로드 받아 사용했습니다.
독학을 해서 코드가 깔끔하지 못한점 양해바랍니다.
개선 사항이 있다면 언제든지 말씀해주세요!