공유자전거 수요량 예측
데이터 수집단계 - 공휴일과 날씨 정보 가져오기
PassionPython
2020. 4. 2. 12:39
1. holiday_gathering
아래 사이트에서 정보를 크롤링하여 가져올 것입니다.
https://www.calendar-365.com/holidays/2011.html
import requests
from bs4 import BeautifulSoup as bs
def month_to_int(month_tgt):
if month_tgt == 'January': return 1
if month_tgt == 'February': return 2
if month_tgt == 'March': return 3
if month_tgt == 'April': return 4
if month_tgt == 'May': return 5
if month_tgt == 'June': return 6
if month_tgt == 'July': return 7
if month_tgt == 'August': return 8
if month_tgt == 'September': return 9
if month_tgt == 'October': return 10
if month_tgt == 'November': return 11
if month_tgt == 'December': return 12
original = pd.DataFrame()
for target in ['2011', '2012']:
req = requests.get('https://www.calendar-365.com/holidays/%s.html' % target)
bs1 = bs(req.text)
bs2 = bs1.find('div', class_ = 'table-scroll-view')
head = bs2.find('thead').find('th')
body_list = bs2.find('tbody').find_all('tr')
year_list, day_list, month_list, holiday_list = [], [], [], []
for line in body_list:
for n, item in enumerate(line.find_all('td')):
if n == 0:
month, day, year = item.text.split(' ')
year_list.append(year)
day_list.append(day)
month_list.append(month_to_int(month))
elif n == 1: holiday_list.append(item.text)
else: break
df = pd.DataFrame()
df['year'] = year_list
df['day'] = day_list
df['month'] = month_list
df['holiday_name'] = holiday_list
original = pd.concat([original, df])
original['holiday'] = 1
original['ymd'] = original['year'].astype(str) +"-"+ original['month'].astype(str) +"-"+ original['day'].astype(str)
original.to_csv('real_holiday.csv', index=False)
2. weather_gathering
날씨의 경우 아래 사이트에서 정보를 가져옵니다.
https://www.worldweatheronline.com/
이틀씩 가져오는 것이므로 여러 번 반복작업이 필요해 for문으로 구현합니다.
구현을 위한 공식 문서는 아래와 같습니다.
https://www.worldweatheronline.com/developer/
아래 구현된 코드에서 api-key가 노출되어 있는데,
하루 사용량 제한이 있는 free-key이므로 그냥 써도 무방합니다만
빠르게 가져오게 되면 ip가 밴당할 수 있으니 유의가 필요합니다.
from datetime import datetime
import time
import json
start_date = datetime.strptime('2011-01-01', '%Y-%m-%d')
str_list = []
for i in range(370):
end_date = start_date + pd.Timedelta(days=1)
base = 'http://api.worldweatheronline.com/premium/v1/past-weather.ashx?key=&key=3e325be0b3154bc19ee95130201502&q=20001&format=json&extra=localObsTime'
start = '&date=%s-%s-%s' % (start_date.year, start_date.month, start_date.day)
end = '&enddate=%s-%s-%s' % (end_date.year, end_date.month, end_date.day)
suffix = '&show_comments=no&tp=1'
url = base + start + end + suffix
str_list.append(requests.get(url).text)
start_date = start_date + pd.Timedelta(days=2)
time.sleep(0.1)
all_req = pd.DataFrame()
for one_req in str_list:
double_date = json.loads(one_req)
single_req_df = pd.DataFrame()
for single_day in double_date['data']['weather']:
date = single_day['date']
by_hour = single_day['hourly']
day_df = pd.DataFrame()
for h_iter in by_hour:
single_hour = {'date' : single_day['date']}
weather_interest = ['time', 'tempC', 'windspeedKmph', 'weatherCode', 'weatherDesc',
'precipMM', 'humidity', 'cloudcover', 'WindGustKmph']
for wi in weather_interest:
single_hour[wi] = h_iter[wi]
day_df = pd.concat([day_df, pd.DataFrame(single_hour, index=[0])], sort=False)
single_req_df = pd.concat([single_req_df, day_df], sort=False)
all_req = pd.concat([all_req, single_req_df], sort=False)
all_req.to_csv('real_weather.csv', index=False)