Python

웹의 데이터로 그래프 그리기

haventmetyou 2023. 10. 31. 12:45
주피터 노트북 사용

기본 code로 되어 있는 것 markdown으로 바꿔서 작성하면

위와 같이 사용 가능

 

웹 페이지의 HTML 가져와 파일로 저장하기

웹 브라우저에서 F12 누르고 개발자 도구 표시

커서 버튼 클릭
가져올 부분 선택

주피터 노트북 만들기

import requests                  # 웹 페이지의 HTML을 가져오는 모듈
from bs4 import BeautifulSoup    # HTML을 파싱하는 모듈

# 웹 페이지를 가져온 뒤 BeautifulSoup 객체로 만듦
response = requests.get('https://pythondojang.bitbucket.io/weather/observation/currentweather.html')
soup = BeautifulSoup(response.content, 'html.parser')

# <table class="table_develop3">을 찾음
table = soup.find('table', { 'class': 'table_develop3' })
data = []                            # 데이터 저장할 리스트 생성
for tr in table.find_all('tr'):      # 모든 tr 태그 찾아 반복(각 지점 데이터 찾기)

    tds = list(tr.find_all('td'))    # 모든 td 태그 찾아 리스트로 만듦(각 날씨 값을 리스트로) 
    
    for td in tds:                   # td 태그 리스트 반복(날씨 값 가져옴)
        if td.find('a'):             # 지점인지 확인
            point = td.find('a').text
            temperature = tds[5].text    # <td> 태그 리스트의 여섯 번째(인덱스5)에서 기온 가져옴
            
            humidity = tds[9].text       # <td> 태그 열 번째에서 습도를 가져옴
            
            data.append([point, temperature, humidity])    # data 리스트에 지점, 기온, 습도 추가
            
data

# 실행 결과
[['서울', '25.6', '30'],
 ['백령도', '18.4', '62'],
 ['인천', '20.8', '54'],
 ['수원', '25.0', '41'],
 ['동두천', '24.9', '34'],
 ['파주', '25.1', '39'],
 ['강화', '20.0', '56'],
 ['양평', '25.5', '32'],
 ['이천', '25.6', '28'],
 ['북춘천', '24.6', '36'],
 ['북강릉', '19.9', '56'],
 ['울릉도', '16.8', '77'],
 ['속초', '19.1', '75'],
 ['철원', '23.9', '37'],
 ['대관령', '17.9', '49'],
 ['춘천', '25.7', '39'],
 ['강릉', '22.7', '41'],
 ['동해', '19.5', '77'],
 ['원주', '23.4', '36'],
 ['영월', '24.2', '34'],
 ['인제', '24.3', '31'],
 ['홍천', '25.4', '25'],
 ['태백', '19.6', '43'],
 ['정선군', '23.0', '32'],
 ['서산', '23.6', '49'],
 ['청주', '24.3', '33'],
 ['대전', '25.1', '37'],
 ['충주', '24.4', '32'],
 ['추풍령', '23.0', '35'],
 ['홍성(예)', '24.3', '46'],
 ['제천', '24.2', '32'],
 ['보은', '23.7', '28'],
 ['천안', '23.5', '35'],
 ['보령', '21.4', '56'],
 ['부여', '23.9', '37'],
 ['금산', '23.7', '30'],
 ['전주', '24.9', '44'],
 ['광주', '24.0', '35'],
 ['목포', '22.8', '51'],
 ['여수', '22.8', '49'],
 ['흑산도', '19.2', '93'],
 ['군산', '21.8', '55'],
 ['완도', '23.2', '45'],
 ['고창', '22.7', '53'],
 ['순천', '22.5', '40'],
 ['진도(첨찰산)', '22.2', '48'],
 ['부안', '22.9', '44'],
 ['임실', '22.8', '40'],
 ['정읍', '23.8', '47'],
 ['남원', '23.8', '35'],
 ['장수', '22.0', '33'],
 ['고창군', '23.7', '48'],
 ['영광군', '22.4', '40'],
 ['순창군', '23.5', '38'],
 ['보성군', '23.7', '34'],
 ['강진군', '24.1', '33'],
 ['장흥', '25.5', '33'],
 ['해남', '24.6', '40'],
 ['고흥', '24.4', '34'],
 ['광양시', '24.6', '43'],
 ['진도군', '21.9', '58'],
 ['제주', '20.7', '60'],
 ['고산', '19.1', '74'],
 ['성산', '23.1', '33'],
 ['서귀포', '24.0', '43'],
 ['안동', '25.0', '32'],
 ['포항', '19.0', '83'],
 ['대구', '25.7', '31'],
 ['울산', '19.7', '70'],
 ['창원', '20.6', '63'],
 ['부산', '20.2', '66'],
 ['울진', '17.6', '84'],
 ['상주', '25.0', '32'],
 ['통영', '20.0', '71'],
 ['진주', '23.8', '30'],
 ['김해시', '21.9', '60'],
 ['북창원', '22.8', '50'],
 ['양산시', '21.4', '63'],
 ['의령군', '25.1', '40'],
 ['함양군', '23.3', '38'],
 ['봉화', '22.0', '38'],
 ['영주', '23.0', '36'],
 ['문경', '25.5', '26'],
 ['청송군', '17.9', '71'],
 ['영덕', '19.4', '57'],
 ['의성', '25.7', '25'],
 ['구미', '25.7', '32'],
 ['영천', '21.8', '47'],
 ['경주시', '23.8', '49'],
 ['거창', '22.7', '38'],
 ['합천', '25.1', '32'],
 ['밀양', '24.7', '34'],
 ['산청', '24.8', '41'],
 ['거제', '23.1', '57'],
 ['남해', '24.5', '40']]

 

데이터를 csv 파일에 저장하기

with open('weather.csv', 'w') as file:    # weather.csv 파일을 쓰기 모드로 열기
    file.write('point, temperature, humidity\n')                  # 컬럼 이름 추가
    for i in data:                                                # data를 반복하면서
        file.write('{0}, {1}, {2}\n'.format(i[0], i[1], i[2]))    # 지점, 온도, 습도를 줄 단위로 저장

메모장이나 기타 텍스트 편집기로 열어 보면

이런 형태로 저장된 것 확인 가능

 

데이터로 그래프 그리기
# %matplotlib inline을 설정하면 matplotlib.pyplot의 show 함수 호출 없이도 주피터 노트북 안에서 그래프가 표시됨
%matplotlib inline
import pandas as pd                # 데이터 저장, 처리하는 패키지
import matplotlib as mpl           # 그래프 그리는 패키지
import matplotlib.pyplot as plt    # 그래프 그리는 패키지

# csv 파일을 읽어 DataFrame 객체로 만듦, 인덱스 컬럼은 point로 설정, 인코딩은 euc-kr로 설정
df = pd.read_csv('weather.csv', index_col='point', encoding='euc-kr')
df

실행 결과

주피터 노트북은 pandas 패키지의 DataFrame을 표 형태로 보여 주므로 편리

 

DataFrame

pandas의 DataFrame은 엑셀 형태의 자료형인데 열(컬럼)과 행(로우)으로 구성되어 있음

csv 파일의 내용을 별도의 처리 없이 그대로 DataFrame으로 가져올 수 있어 편리함

단, csv 파일의 첫 줄에는 point, temperature, humidity처럼 컬럼 이름이 들어 있어야 함

 

특별시 광역시만 모으기

# 특별시, 광역시만 모아 DataFrame 객체 만듦
city_df = df.loc[['서울', '인천', '대전', '대구', '광주', '부산', '울산']]
city_df

· DataFrame객체.loc['인덱스]

· DataFrame객체.loc[['인덱스1', '인덱스2']]

df.loc['서울']

df.loc[['서울', '부산']]

 

특별시, 광역시만 그래프 그리기

# Windows 한글 폰트 설정
font_name = mpl.font_manager.FontProperties(fname='C:/Windows/Fonts/malgun.ttf').get_name()
mpl.rc('font', family=font_name)

# 차트 종류, 제목, 차트 크기, 범례, 폰트 크기 설정
ax = city_df.plot(kind='bar', title='날씨', figsize=(12, 4), legend=True, fontsize=12)
ax.set_xlabel('도시', fontsize=12)          # x축 정보 표시
ax.set_ylabel('기온/습도', fontsize=12)     # y축 정보 표시
ax.legend(['기온', '습도'], fontsize=12)    # 범례 지정