반응형
일기예보를 보기 위해 네이버에서 노원구 날씨를 검색했다.
그날의 시간별 기온을 그래프로 보여준다.
그런데 주간예보는 최저, 최고 기온을 표로 나타내어 가독성이 떨어진다.
그래서 기온(+날씨)을 웹스크래핑하여 가져온 후 이를 그래프로 나타내보았다.
1. 사용할 라이브러리를 불러온다.
#정적 웹페이지 데이터 가져오기
from bs4 import BeautifulSoup
import requests
#데이터 저장 및 분석하기
import pandas as pd
#오늘의 날짜
from datetime import datetime
#정규식
import re
#그래프 그리기
import matplotlib
import matplotlib.pyplot as plt
2. 노원구 날씨 데이터를 웹스크래핑한다.
#[오늘을 포함한 5일치의 날씨 / 최고 및 최저 기온 / 미세먼지]
#1-1. 오늘을 포함한 5일치의 날씨
#만약 노원구가 아닌 다른 지역의 날씨를 얻고자 한다면 url_weather 수정하기
url_weather = "https://search.naver.com/search.naver?ie=UTF-8&sm=whl_hty&query=%EB%85%B8%EC%9B%90%EA%B5%AC+%EB%82%A0%EC%94%A8"
res_weather = requests.get(url_weather)
res_weather.raise_for_status()
soup_weather = BeautifulSoup(res_weather.text, "lxml")
data_weather_all = soup_weather.find_all("li", attrs={"class":"week_item today", "class":"week_item"})
#2_오전, 강수확률, 날씨, 오후, 강수확률, 날씨
list_weather_all = [] #모든 데이터를 넣을 리스트
count_weather = 1 #5일치만 가져오기 위한 변수 설정
for data_weather in data_weather_all:
if count_weather == 6: #5일치만 가져올 것이므로
break
list_weather = [] #반복문 안의 데이터를 넣을 리스트
#요일
list_weather.append(data_weather.find_all("div")[0].find("strong", attrs={"class":"day"}).text)
#날짜
if len(data_weather.find_all("div")[0].find("span", attrs={"class":"date"}).text) == 5:
list_weather.append(datetime.today().strftime("%Y") + ".0" + data_weather.find_all("div")[0].find("span", attrs={"class":"date"}).text)
else:
list_weather.append(datetime.today().strftime("%Y") + "." + data_weather.find_all("div")[0].find("span", attrs={"class":"date"}).text)
#오전강수확률
#숫자만 가져오기 위해 re.findall("\d+", 문자열) 활용
list_weather.append(int(re.findall("\d+", data_weather.find_all("div")[0].find_all("span", attrs={"class":"rainfall"})[0].text)[0]))
#오후강수확률
list_weather.append(int(re.findall("\d+", data_weather.find_all("div")[0].find_all("span", attrs={"class":"rainfall"})[1].text)[0]))
#오전날씨
list_weather.append(data_weather.find_all("div")[0].find_all("span", attrs={"class":"blind"})[0].text)
#오후날씨
list_weather.append(data_weather.find_all("div")[0].find_all("span", attrs={"class":"blind"})[1].text)
#최저기온
#기온이 - 일수도 있으므로 re.findall("-|[\d+]") 활용. 그리고 해당 값들을 모두 하나의 문자열로 바꾸기 위한 join 함수
list_weather.append(int("".join(re.findall("-|[\d+]", data_weather.find("div").find("span", attrs={"class":"lowest"}).text))))
#최고기온
list_weather.append(int("".join(re.findall("-|[\d+]", data_weather.find("div").find("span", attrs={"class":"highest"}).text))))
#전체 리스트에 넣기
list_weather_all.append(list_weather) #모든 데이터를 넣을 리스트에 반복문에서 수합한 데이터 넣기
count_weather += 1 #총 5일의 데이터를 가져오기 위해 반복문 마지막에 변수 +1
#DataFrame 만들기
df_weather = pd.DataFrame(list_weather_all, columns=["요일", "날짜", "오전강수확률", "오후강수확률", "오전날씨", "오후날씨", "최저기온", "최고기온"])
3. 꺾은선 그래프를 그린다.
import matplotlib
import matplotlib.pyplot as plt
matplotlib.rcParams["font.family"] = "Malgun Gothic" #한글폰트로 설정. 미설정시 한글 깨짐
plt.plot(df_weather["날짜"], df_weather["최저기온"], label = "최저기온") #날짜에 따른 최저기온 그래프
plt.plot(df_weather["날짜"], df_weather["최고기온"], label = "최고기온") #날짜에 따른 최고기온 그래프
plt.legend(loc=5) #범례 위치 설정
plt.title("노원구 날씨") #그래프 제목 설정
for index, value in enumerate(df_weather["날짜"]): #그래프 위에 기온과 날씨 텍스트 삽입
plt.text(df_weather["날짜"][index], df_weather["최저기온"][index],
str(df_weather["최저기온"][index]) + "," + df_weather["오전날씨"][index])
plt.text(df_weather["날짜"][index], df_weather["최고기온"][index],
str(df_weather["최고기온"][index]) + "," + df_weather["오전날씨"][index])
plt.show() #그래프 보이기
4. 그래프 완성!
여담
인터넷에 검색하면 쉽게 나오는 정보인데, 조금 불편해도 그 정도는 괜찮지 않냐고 할 수 있다.
맞다! 하지만 나에게 적합하게, 조금 더 편하게 볼 수 있도록 만들 수 있는데... 그냥 불편함을 감수하는 것도 뭔가 찜찜하지 않은가.
반응형
'데이터 분석' 카테고리의 다른 글
워드클라우드 만들기 기초 활용! (0) | 2022.03.03 |
---|---|
2020년 서울 주거지, 수변부, 공원 모기지수 그래프로 나타내기 (2) | 2022.02.28 |
matplotlib 그래프 이미지가 잘린 상태로 저장될 때 (2) | 2022.02.23 |
2021학년도 전국 초등학교 전출입 학생 수 평균 그래프 (0) | 2022.02.22 |
학교알리미로 2021 전국 초등학교 입학생 수 그래프 그리기 (0) | 2022.02.19 |
댓글