IT/파이썬

[코딩도장] day34. 파이썬: (실전예제) 웹의 데이터로 그래프 그리기

_하늘여우_ 2020. 10. 10. 01:50

출처 : unsplash

 

■ 들어가기

- 파이썬 코딩 도장 (남재윤/길벗). 을 공부하며 정리하는 블로그


▶ Unit46. 실전예제: 웹의 데이터로 그래프 그리기

     - 46.1 아나콘다 설치하기

     - 46.2 주피터 노트북 사용하기

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

     - 46.4 데이터로 그래프 그리기

 

 

0. 들어가기

- 최근 파이썬은 데이터 처리와 분석 분야에서 사용되고 있음

- 웹에서 데이터 가져온 후(crawling) 그래프 그리기 실습

- 웹 페이지 접근 > HTML 가져오기 > 필요한 데이터를 추출하여 파일로 저장 > 데이터를 읽어 > 그래프 그리기

출처 : 파이썬 코딩 도장 (dojang.io)

- 기상청(www.kma.go.kr)의 도시별 현재날씨 페이지에서 기온과 습도 추출하여 그래프 그리기

 

 

>> 46.1 아나콘다 설치하기 <<

- 주요 기능이 구현된 파이썬 패키지를 사용하는데

- 리눅스/맥OS에서는 pip 패키지 설치가 문제없으나, 윈도우에서는 에러 발생하는 경우가 많아

- 주요 패키지 포함된 파이썬 배포판을 활용

 

1. 아나콘다 설치 파일 받기

위치 : www.anaconda.com/products/individual

- 자신의 OS버전에 맞게 다운로드!

- '20.10.09 현재 파이썬 3.8 버전 다운로드 받음

- 파일명: Anaconda3-2020.07-Windows-x86_64.exe

 

 

 

>> 46.2 주피터 노트북 사용하기 <<

- 주피터 노트북: 웹 브라우저에서 파이썬 코드를 작성하고 실행할 수 있는 툴

 

1. 주피터 노트북 실행하기

- 시작 > Anaconda3 (64-bit) > Jupyter Notebook (Anaconda3)

- 실행하면 아래의 콘솔창이 뜨면서 로그를 찍고, 이후 웹 브라우저가 실행되면서 주피터 노트북이 나타남

 

2. 파이썬 노트북 만들기

- 우상단 New > Python3 클릭

 

3. 설명 추가하기

- 문서 편집기같은 화면이 나타나며, 메뉴 드롭다운의 Markdown 을 선택

- 아래 내용을 입력

- #는 설명 입력 시 사용 하는 부분 (제목이 되고, #를 붙일 수록 하위 제목으로 봄)

## Hello, world! 출력
print 함수로 Hello, world!를 출력합니다.

 

4. 파이썬 코드 입력하기

- 3에서 설명 입력 후 Run 버튼 클릭하면 설명이 적용되고 아래에 셀이 생기며

- In []: 이 파이썬 코드를 입력할 수 있는 명령줄이 됨

- 입력 후 Run 수행하면 새로운 줄이 생기며 이전 입력 코드에 숫자가 생성됨 (x번째로 실행된 코드라는 의미)

 

5. 노트북의 제목 바꾸기

- jupyter 로고 옆 Untitled 를 클릭하여 제목 변경

- File > Save and Checkpoint를 클릭하여 파일로 저장 (확장자: .ipynb)

 

 

>> 46.3 웹 페이지의 HTML을 가져와서 파일로 저장하기 <<

- 기상청 웹 페이지에서 HTML을 가져오기 위해 페이지 이동

- 경로: www.weather.go.kr/weather/observation/currentweather.jsp

- 제시된 도표에서 지점, 기온(현재기온), 습도 만 추출

 

 

1. 가져올 HTML 확인하기

- 개발자 도구 실행(F12, 크롬 브라우저)

- 좌측 화면에서 '지점' 글씨 클릭하면 우측 Elements의 소스 코드가 표시되는데

- 위로 조금 올려 <table class="table_develop3" 부분을 클릭 => 표 전체가 표시

 

 

2. 주피터 노트북 만들기

- 시작 > cmd

- 아래 명령어로 주피터 노트북에 프로젝트 폴더를 c:\project 로 지정

- 아나콘다 기본 설치 경로 : C:\ProgramData\Anaconda3 (만일 사용자가 변경했으면 해당 경로)

C:\ProgramData\Anaconda3\python.exe -m notebook --notebook-dir c:\project

- 만일 위의 명령어 수행 중 에러가 발생할 경우, Anaconda Prompt를 수행하여 다시 입력한다!

- 경로: 시작 > Anaconda3 (64-bit) > Anaconda Prompt (Anaconda3)

- 그러면 새로 웹 브라우저 창이 뜨면서 c:\project 를 프로젝트 폴더로 하여 하위 파일들이 확인된다!

- 단, 해당 콘솔창을 닫으면 안됨!

- New > Python3 클릭 후 코드 셀에 코드 입력

- 파일명 바꾸고 c:\project 폴더 이동하여 해당 파일이 생성되었는지 확인!

소스 (weather.ipynb)
import requests   # 웹 페이지의 HTML을 가져오는 모듈
from bs4 import BeautifulSoup   # HTML을 파싱하는 모듈

# 웹 페이지를 가져온 뒤 BeautifulSoup 객체로 만듦
response = requests.get('http://www.weather.go.kr/weather/observation/currentweather.jsp')
# 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'))   # 모든 <tr> 태그를 찾아서 리스트로 만듦
    for td in tds :    # <td> 태그 리스트 반복
        if td.find('a') :    # <td> 안에 <a> 태그가 있으면 (지점인지 확인)
            point = td.find('a').text   # <a> 태그 안에서 지점을 가져옴
            temperature = tds[5].text   # <td> 태그 리스트의 여섯 번째(인덱스 5)에서 기온을 가져옴
            humidity = tds[9].text      # <td> 태그 리스트의 열 번째(인덱스 9)에서 습도를 가져옴
            data.append([point, temperature, humidity])   # data 리스트에 지점, 온도, 습도를 추가
            
data   # data 표시. 주피터 노트북에서는 print를 사용하지 않아도 변수의 값이 표시됨

가져온 데이터 확인

 

3. HTML의 데이터를 가져오는 방식 알아보기

- 크롬 개발자도구로 확인하면, 표는 <table>에서 데이터는 <tr> 태그로 묶여 있고, 세부 값은 <td> 태그에 있음

- <a> 태그가 존재 시, 지점으로 판단하며

- 5번 째 인덱스가 현재기온

- 9번 째 인덱스가 습도 로 판단

- requests 모듈로 웹 페이지의 HTML을 가져오고, bs4 모듈로 HTML을 파싱

- 위의 방법은 "웹 페이지 크롤링" 으로 웹 페이지의 데이터를 추출하는 방법

 

 

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

- 데이터 출력부 하단에 새로 생성된 코드 셀에 다음 코드 입력

- 코드 실행 시 c:\project 폴더 내 weather.csv 파일이 생성되는지 확인!

소스 (weather.ipynb 계속)
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]))   # 지점, 온도, 습도를 줄 단위로 저장
결과
point,temperature,humidity
강릉,16.1,73
강진군,12.6,87
강화,14.5,66
거제,18.4,63
거창,14.1,72
경주시,18.1,64
...

 

 

>> 46.4 데이터로 그래프 그리기 <<

- 앞서 진행하였던 주피터 노트북에 이어서 아래 코드 작성

소스 (weather.ipynb 계속)
# weather.csv 파일을 읽어서 pandas의 DataFrame 걕체로 만듦 (pandas는 데이터 처리 시 사용하는 패키지)
# %matplotlib inline을 설정하면 matplotlib.pyplot의 show 함수를 호출하지 않아도
# 주피터 노트북 안에서 그래프가 표시됨
%matplotlib inline
import pandas as pd               # 데이터를 저장하고 처리하는 패키지
import matplotlib as mpl          # 그래프를 그리는 패키지
import matplotlib.pyplot as plt   # 그래프를 그리는 패키지

# csv 파일을 읽어서 DataFrame 객체로 만듦. 인덱스 컬럼은 point로 설정
df = pd.read_csv('weather.csv', index_col='point', encoding='euc-kr')   # HTML이 euc-kr로 만들어져서 읽을 때도 euc-kr 설정
df   # df 표시

- 결과 : 이쁘게 표로 출력된다!!!

 

1. 특별시 광역시만 모으기

- df에서 특별시, 광역시만 모아서 따로 DataFrame 객체를 만듦

- DataFrame은 엑셀 형태의 자료형이며, 컬럼(열)과 로우(행) 으로 구성됨

소스 (weather.ipynb 계속)
# 특별시, 광역시만 모아서 DataFrame 객체로 만듦
city_df = df.loc[['서울', '인천', '대전', '대구', '광주', '부산', '울산']]
city_df   # city_df 표시

- DataFrame의 loc 속성을 이용해서 특정 인덱스의 데이터만 가져옴

(loc: label-location의 약자, 레이블을 지정해 특정 인덱스의 데이터 추출 시 사용)

- loc 에 인덱스를 하나만 지정하면 해당 인덱스의 데이터만 추출

- 인덱스 여러 개를 리스트 형태로 지정하면 DataFrame 형태로 가져옴 (인덱스는 문자열로 지정!)

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

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

 

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

소스 (weather.ipyn 계속)
# 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)   # 범례 지정

 

끝!!!