ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 실시간 날씨 예보를 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에서 다운로드 받아 사용했습니다.

     

    독학을 해서 코드가 깔끔하지 못한점 양해바랍니다.

    개선 사항이 있다면 언제든지 말씀해주세요!

     

Designed by Tistory.