작년 한 해 서울의 기온은 어떻게 변했을까요? 이런 작업을 하려면 날씨정보가 어디있는지 알아야 하고, 그 정보를 활용해서 우리가 보고싶은 모습으로 표현할 수 있어야 합니다. Weather Underground에서는 전세계의 날씨 데이터를 일자별, 주별, 월별, 기간별로 제공하고 있습니다.





한 가지 문제가 있습니다. 우리가 원하는 것은 일별 데이터인데 모두 확인하려면 대단한 노가다(?)를 해야한다는 것입니다. 파이썬의 Beautiful Soup 라이브러리를 활용하면 이 작업을 쉽게 처리할 수 있습니다. Beautiful Soup라이브러리는 html과 xml로 부터 데이터를 뽑아내기 위한 라이브러리 입니다. Beautiful Soup Document를 보시면 자세한 내용을 확인 할 수 있습니다.


이 라이브러리를 활용해서 서울의 기온데이터를 뽑아보도록 하겠습니다. 코드는 네이선 야우의 Visualize This를 참고하였습니다. 원래 파이썬 2로 작성된 것을 파이썬 3에서 평균기온, 최고기온, 최저기온을 추가로 표시할 수 있도록 수정한 것입니다.

#!-#-coding: utf8-*-

import urllib.request
from bs4 import BeautifulSoup

# 기온데이터를 저장할 파일을 쓰기모드로 연다
f = open('wunder-data-seoul.txt', 'w')

# 1월에서 12월까지 각 날짜의 페이지를 순회하면서 기온정보를 뽑아낸다
for m in range(1, 13):
    for d in range(1, 32):
        if (m == 2 and d > 28):   #2월이 28일을 넘으면 중단하고 다음 달로 넘어간다
            break
        elif (m in [4, 6, 9, 11] and d > 30):  #4, 6, 9, 11월이 30일을 넘으면 중단하고 다음 달로 넘어간다
            break
        
        if (len(str(m)) == 1) and (len(str(d)) == 1):
            timestamp = '20130' + str(m) + '0' + str(d)
        elif (len(str(m)) == 1) and (len(str(d)) == 2):
            timestamp = '20130' + str(m) + str(d)
        elif (len(str(m)) == 2) and (len(str(d)) == 1):
            timestamp = '2013' + str(m) + '0' + str(d)
        else:
            timestamp = '2013' + str(m) + str(d)
            
       	# 뽑아내려는 기온데이터가 들어있는 페이지를 urllib 라이브러리로 불러온다
        url = "http://english.wunderground.com/history/airport/RKSS/2013/" \
				+ str(m) + "/" + str(d) + \
				"/DailyHistory.html?req_city=NA&req_state=NA&req_statename=NA"
        page = urllib.request.urlopen(url)
        
	# Beautiful Soup 라이브러리로 기온데이터를 추출한다. 
	# 기온데이터는 nobr 클래스에 span태그로 둘러싸여 있다.
        soup = BeautifulSoup(page)
        dayMeanTemp = soup.find_all('span', attrs={"class":"nobr"})[0].span.string
        dayMaxTemp = soup.find_all('span', attrs={"class":"nobr"})[1].span.string
        dayMinTemp = soup.find_all('span', attrs={"class":"nobr"})[4].span.string

        print('date: {0},{1},{2},{3}'.format(timestamp, dayMeanTemp, dayMaxTemp, dayMinTemp))
        
        if len(str(m)) < 2:
            mStamp = '0' + str(m)
        else:
            mStamp = str(m)
            
        if len(str(d)) < 2:
            dStamp = '0' + str(d)
        else:
            dStamp = str(d)
        
        timestamp = '2013' + mStamp + dStamp
        
	#읽어온 기온데이터를 파일에 쓴다
	f.write(timestamp + ',' + dayMeanTemp + ',' + dayMaxTemp + ',' + dayMinTemp + '\n')

# 모든 데이터를 읽었으면, 기온데이터를 저장한 파일을 닫는다
f.close()

이제 서울의 2013년 기온데이터 365개를 일자별로 얻었습니다. 세부 데이터는 첨부파일을 참고하세요


get-weather-data-seoul.txt



Beautiful Soup라이브러리의 HTML, XML 파싱이 필요한 어디에서는 사용할 수 있습니다. 즐겁게 사용해 보시기 바랍니다. 


댓글을 달아 주세요

  1. 모르겠어요

    소스를 그대로 따라해보니
    Traceback (most recent call last):
    File "C:/Python34/aaa.py", line 35, in <module>
    soup = BeautifulSoup(page)
    File "C:\Python34\lib\site-packages\bs4\__init__.py", line 172, in __init__
    self._feed()
    File "C:\Python34\lib\site-packages\bs4\__init__.py", line 185, in _feed
    self.builder.feed(self.markup)
    File "C:\Python34\lib\site-packages\bs4\builder\_htmlparser.py", line 146, in feed
    parser.feed(markup)
    File "C:\Python34\lib\html\parser.py", line 165, in feed
    self.goahead(0)
    File "C:\Python34\lib\html\parser.py", line 222, in goahead
    k = self.parse_starttag(i)
    File "C:\Python34\lib\html\parser.py", line 413, in parse_starttag
    self.handle_starttag(tag, attrs)
    File "C:\Python34\lib\site-packages\bs4\builder\_htmlparser.py", line 48, in handle_starttag
    self.soup.handle_starttag(name, None, None, dict(attrs))
    File "C:\Python34\lib\site-packages\bs4\__init__.py", line 298, in handle_starttag
    self.currentTag, self.previous_element)
    File "C:\Python34\lib\site-packages\bs4\element.py", line 749, in __init__
    self.name, attrs)
    File "C:\Python34\lib\site-packages\bs4\builder\__init__.py", line 160, in _replace_cdata_list_attribute_values
    values = whitespace_re.split(value)
    TypeError: expected string or buffer

    이런 에러가 나타나는데 왜 그런가요??

    2015.03.06 19:18 신고 Address Modify/Delete Reply
  2. 지나가던_사람

    글 잘 읽었습니다. 파이썬이 이렇게 유용하게 쓰일 수 있다는 게 참 좋은 것 같습니다. 그런데 올라온 파일, get-weather-data-seoul.txt, 다운받아서 matplotlib으로 그래프를 그려본 결과 몇몇 잘못된 데이터 row가 있습니다. 10 이상인 걸로 보아 꽤 많더라고요. 그 부분 수정이 필요할 것 같습니다.

    2015.07.16 04:55 신고 Address Modify/Delete Reply