-
[파이썬] 웹 크롤러 + Tkinter : 기상청 일기예보Python/파이썬 웹 크롤러 2022. 12. 18. 22:11반응형
https://www.weather.go.kr/w/pop/rss-guide.do
아래 코드는 1.5시간에 1번씩 기상청 RSS를 크롤링해온다.
필요 이상의 과도한 크롤링은 서버 부담만 늘릴 뿐이다.서울 강남 개포1동 RSS 주소 : https://www.kma.go.kr/wid/queryDFSRSS.jsp?zone=1168066000
import tkinter as tk import xml.etree.ElementTree as ET from datetime import datetime, timedelta from urllib import request def crawl(): r = request.urlopen("https://www.kma.go.kr/wid/queryDFSRSS.jsp?zone=1168066000") xml_text = r.read().decode() xml_root = ET.fromstring(xml_text) announce_time = datetime.strptime(xml_root.find('.//tm').text, '%Y%m%d%H%M') result = xml_root.find('.//item/category').text + '\n' result += f"발표: {announce_time.strftime('%Y-%m-%d %H:%M')}" + '\n' for each in xml_root.findall('.//data'): if each.find('day').text == '2': continue forecast_date = announce_time + timedelta(days=int(each.find('day').text)) result += f"{forecast_date.strftime('%d')}일 " \ f"{each.find('hour').text:>02}시, " \ f"{float(each.find('temp').text):.0f}℃, " \ f"{each.find('wfKor').text}, " \ f"강수확률: {each.find('pop').text}, " \ f"습도: {each.find('reh').text}, " \ f"풍속: {float(each.find('ws').text):.1f}" \ '\n' return result def repeat(): weather_text = crawl() lbl.config(text=weather_text) root.after(5_400_000, repeat) # 1.5시간 = 90분 = 5400초 root = tk.Tk() root.geometry('360x240') root.title('오늘의 날씨') lbl = tk.Label(root, text='') lbl.pack() repeat() root.mainloop()
root.after(5_400_000, repeat, root, lbl) # after함수는 root의 mainloop에 실행 예약을 한다. # 5_400 초 뒤에, repeat 함수에 root, lbl을 넣어서 (= repeat(root, lbl)) 실행해줘.
간단하게 작동만 확인해 보았다. 아래 페이지를 참고하여 화면을 수정해 보자.
전역변수는 일반적으로 피하는 게 좋다.
전역변수를 사용하지 않고 코딩한다면 이렇게...import tkinter as tk import xml.etree.ElementTree as ET from datetime import datetime, timedelta from urllib import request def crawl(): r = request.urlopen("https://www.kma.go.kr/wid/queryDFSRSS.jsp?zone=1168066000") xml_text = r.read().decode() xml_root = ET.fromstring(xml_text) announce_time = datetime.strptime(xml_root.find('.//tm').text, '%Y%m%d%H%M') result = xml_root.find('.//item/category').text + '\n' result += f"발표: {announce_time.strftime('%Y-%m-%d %H:%M')}" + '\n' for each in xml_root.findall('.//data'): if each.find('day').text == '2': continue forecast_date = announce_time + timedelta(days=int(each.find('day').text)) result += f"{forecast_date.strftime('%d')}일 " \ f"{each.find('hour').text:>02}시, " \ f"{float(each.find('temp').text):.0f}℃, " \ f"{each.find('wfKor').text}, " \ f"강수확률: {each.find('pop').text}, " \ f"습도: {each.find('reh').text}, " \ f"풍속: {float(each.find('ws').text):.1f}" \ '\n' return result def repeat(root, lbl): weather_text = crawl() lbl.config(text=weather_text) root.after(5_400_000, repeat, root, lbl) # 1.5시간 = 90분 = 5400초 def main(): root = tk.Tk() root.geometry('360x240') root.title('오늘의 날씨') lbl = tk.Label(root, text='') lbl.pack() repeat(root, lbl) root.mainloop() if __name__ == '__main__': main()
GUI로써의 기본적인 외형 + 가독성은 갖추어야 되겠다 싶어...
import tkinter as tk import xml.etree.ElementTree as ET from datetime import datetime, timedelta from urllib import request def crawl(): r = request.urlopen("https://www.kma.go.kr/wid/queryDFSRSS.jsp?zone=1168066000") xml_text = r.read().decode() xml_root = ET.fromstring(xml_text) announce_time = datetime.strptime(xml_root.find('.//tm').text, '%Y%m%d%H%M') result = xml_root.find('.//item/category').text + '\n' result += f"발표: {announce_time.strftime('%Y-%m-%d %H:%M')}" + '\n' for each in xml_root.findall('.//data'): # if each.find('day').text == '2': # continue forecast_date = announce_time + timedelta(days=int(each.find('day').text)) result += f"{forecast_date.strftime('%d')}일 " \ f"{each.find('hour').text:>02}시, " \ f"{float(each.find('temp').text):.0f}℃, " \ f"{each.find('wfKor').text}, " \ f"강수확률: {each.find('pop').text}, " \ f"습도: {each.find('reh').text}, " \ f"풍속: {float(each.find('ws').text):.1f}" \ '\n' return result def repeat(root, txt): root.after(5_400_000, repeat, root, txt) # 1.5시간 = 90분 = 5400초 weather_text = crawl() weather_text += f"최종 확인: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}" txt.delete(1.0, tk.END) txt.insert(tk.CURRENT, weather_text) def main(): root = tk.Tk() root.geometry('400x360') root.title('오늘의 날씨') txt = tk.Text(root, height=24, font=('맑은 고딕', 9)) txt.pack() repeat(root, txt) root.mainloop() if __name__ == '__main__': main()
반응형