Skip to content

Instantly share code, notes, and snippets.

@2minchul
Last active March 28, 2019 08:33
Show Gist options
  • Select an option

  • Save 2minchul/a8cabbc8e86bb14c9f7e38859fca4f14 to your computer and use it in GitHub Desktop.

Select an option

Save 2minchul/a8cabbc8e86bb14c9f7e38859fca4f14 to your computer and use it in GitHub Desktop.
# coding=utf-8
import re
import requests
from bs4 import BeautifulSoup, Tag
weather_pattern = re.compile(
r'''(?P<name>[^<>]+?) # name group
\s*?:\s*? # split by ':'
(?P<value> # value group
(?:
[-+]? # optional: '-' or '+'
(?:\d*[.]\d+)|(?:\d+[.]?) # (.d or d.d) or (d. or d)
) | - # or just '-'
)''',
re.VERBOSE # 정규표현식에 주석을 허용하고 공백은 무시
)
stn_table = {'서울': '108', '백령도': '102', '동두천': '98', '파주': '99', '인천': '112', '수원': '119',
'강화': '201', '양평': '202', '이천': '203', '북춘천': '93', '철원': '95', '춘천': '101',
'원주': '114', '영월': '121', '인제': '211', '홍천': '212', '북강릉': '104', '울릉도': '115',
'강릉': '105', '속초': '90', '대관령': '100', '동해': '106', '태백': '216', '정선군': '217',
'청주': '131', '충주': '127', '추풍령': '135', '제천': '221', '보은': '226', '홍성': '177',
'대전': '133', '서산': '129', '천안': '232', '보령': '235', '부여': '236', '금산': '238',
'전주': '146', '군산': '140', '부안': '243', '임실': '244', '정읍': '245', '남원': '247',
'장수': '248', '순창': '254', '고창': '172', '고창(구)': '251', '광주': '156', '목포': '165',
'흑산도': '169', '여수': '168', '완도': '170', '진도(첨찰산)': '175', '진도군': '268', '영광': '252',
'순천': '174', '순천(구)': '256', '장흥': '260', '해남': '261', '고흥': '262', '강진군': '259',
'보성군': '258', '광양': '266', '안동': '136', '포항': '138', '대구': '143', '대구(구)': '176',
'울진': '130', '상주': '137', '봉화': '271', '영주': '272', '문경': '273', '영덕': '277',
'의성': '278', '구미': '279', '영천': '281', '청송군': '276', '경주': '283', '부산': '159',
'울산': '152', '창원': '155', '북창원': '255', '통영': '162', '진주': '192', '거창': '284',
'합천': '285', '밀양': '288', '산청': '289', '거제': '294', '남해': '295', '김해시': '253',
'양산': '257', '의령군': '263', '함양군': '264', '제주': '184', '고산': '185', '서귀포': '189',
'성산': '188'}
def get_weather(local, year, month, raise_if_failure=False):
stn_code = local if local.isdigit() else stn_table.get(local)
if not stn_code: # 없는 stn 코드
return
response = requests.get(
'http://www.weather.go.kr/weather/climate/past_cal.jsp',
params={'stn': stn_code, 'yy': str(year), 'mm': str(month), 'obs': '1'}
)
if raise_if_failure:
response.raise_for_status()
return response.text
def parse_weather(html):
if not html:
return
soup = BeautifulSoup(html, 'html.parser')
table = soup.find('table', {'class': 'table_develop'}) # type: Tag
tr_object = iter(table.find_all('tr'))
week_list = []
for th_ in next(tr_object).find_all('th'): # type: Tag
week_list.append(th_.text.strip())
def th_generator():
while True:
try:
yield next(tr_object).find_all('td'), next(tr_object).find_all('td')
except StopIteration:
break
for day_td_list, weather_td_list in th_generator():
for day_tr, weather_tr, week in zip(day_td_list, weather_td_list, week_list): # type: (Tag, Tag, str)
day = day_tr.text.strip()
if day:
yield week, day, {rex.group('name'): rex.group('value') for rex in
weather_pattern.finditer(str(weather_tr))}
if __name__ == '__main__':
print('서울')
html = get_weather('서울', 2019, 3)
for week, day, data in parse_weather(html):
print(week, day, data)
print('대전')
html = get_weather('대전', 2018, 2)
for week, day, data in parse_weather(html):
print(week, day, data)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment