爬取全国未来十五天的天气数据
- 一、网页分析
- (一)请求分析(url)
- 1、观察
- 2、分析
- 3、结论
- (二)行政区域分析
- 1、观察
- 2、分析
- 3、结论
- (三)未来15日 天气数据分析
- 1、观察
- 2、分析
- 3、结论
- 二、数据提取
- (一)请求页面
- (二)根据url获取行政区域
- (三)获取未来15天的天气数据
- (四)数据保存
- (五)主函数
一、网页分析
(一)请求分析(url)
1、观察
北京海淀区 天气预报15天:https://www.tianqi.com/haidian/15/ 北京朝阳区 天气预报15天:https://www.tianqi.com/chaoyang/15/ 北京朝阳区 天气预报30天:https://www.tianqi.com/chaoyang/30/
https://www.tianqi.com/haidian/15/ https://www.tianqi.com/chaoyang/30/
2、分析
- https://www.tianqi.com:网址
/haidian/:行政区域
15/:未来15天
3、结论
- 改变请求(url)中的“行政区域”部分就可以获取不同城市地区的未来15日天气数据。
(二)行政区域分析
1、观察
点击:【天气】——>【全国】
获取行政区域:https://www.tianqi.com/chinacity.html
2、分析
<div class=“citybox”>
- <h2>:包含省份(provinces)
- <span>:省份下的城市(citys)<a>
3、结论
通过提取 <div class=“citybox”> 下的信息就可获取到全国行政区域
(三)未来15日 天气数据分析
1、观察
重庆渝中未来15日天气:https://www.tianqi.com/yuzhongqu/15/
2、分析
<div class=“inleft”> :大类别
- <ul class=“weaul”>:未来15日天气数据
– <li>:每一天的天气数据
3、结论
通过提取 <div class=“inleft”> 下的信息就可获取每个城市未来15日的天气状况
二、数据提取
(一)请求页面
- get_html_soup(url) 函数,通过请求地址(url),返回soup(BeautifulSoup解析后的界面)
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36',
'Cookie': 'cityPy=kunming; cityPy_expire=1561950588; UM_distinctid=17133bbc7e6685-0b6045e36118e6-4313f6a-144000-17133bbc7e7a8e; CNZZDATA1275796416=1819259675-1585710340-%7C1585715624; Hm_lvt_ab6a683aa97a52202eab5b3a9042a8d2=1585710877,1585712908,1585712984,1585716742; Hm_lpvt_ab6a683aa97a52202eab5b3a9042a8d2=1585716834'
}
'''
功能:请求页面
parameters:
url:请求地址
return:
soup:BeautifulSoup解析后的界面
'''
def get_html_soup(url):
req = requests.get(url, headers=headers)
req.encoding = 'utf-8'
html = req.text
soup = BeautifulSoup(html, 'lxml')
return soup
(二)根据url获取行政区域
<div class=“citybox”>
- <h2>:包含省份(provinces)
- <span>:省份下的城市(citys)<a>
get_admArea(url) 函数
- url:获取行政区域
- 返回provinces_citys:——格式:list[string]:string如:‘ 北京,/beijing/,海淀,/haidian/ ’
'''
功能:根据url获取行政区域
parameters:
url:页面请求地址
return:
provinces_citys:list[string]:【北京,/beijing/,海淀,/haidian/】
'''
def get_admArea(url):
# 省份及其城市
provinces_citys = []
# 请求页面
soup = get_html_soup(url)
cityBox = soup.find('div', class_='citybox')
province_list = cityBox.find_all('h2')
city_list = cityBox.find_all('span')
# print(len(province_list))#31
# 提取数据
for i in range(len(province_list)):
# 省份
province_name = province_list[i].a.get_text() # h2下的<a>标签下的内容
province_url = province_list[i].a['href'] # h2下的<a>标签下的href
# print(province_name,province_url)
# 城市
citys = city_list[i].find_all('a')
for j in range(len(citys)):
city_name = citys[j].get_text()
city_url = citys[j]['href']
str = province_name + ',' + province_url + ',' + city_name + ',' + city_url # 以字符串形式存储
provinces_citys.append(str)
# 返回省份及其城市
return provinces_citys
(三)获取未来15天的天气数据
<div class=“inleft”> :大类别
- <ul class=“weaul”>:未来15日天气数据
– <li>:每一天的天气数据
get_15_weather(provinces_city, year) 函数:
- provinces_city:行政区域字符串string(格式:【北京,/beijing/,海淀,/haidian/】)
- year: 年份<class ‘str’>如:‘2020’
- 返回city_weather_list 天气状况:string‘北京,/beijing/,海淀,/haidian/,20200702,小雨,20,27,优,东风,2’
'''
功能:获取未来15天的天气数据
parameters:
provinces_city:行政区域字符串string(格式:【北京,/beijing/,海淀,/haidian/】)
year:年份<class 'str'>如:'2020'
return:
city_weather_list天气状况:string‘北京,/beijing/,海淀,/haidian/,20200702,小雨,20,27,优,东风,2’
'''
def get_15_weather(provinces_city, year):
year_now = year # 年份<class 'str'>
# https: // www.tianqi.com / yuzhongqu / 15 /
city_weather_list = [] # 城市天气信息
tianqi_url = 'http://tianqi.com' # 历史天气
content_list = provinces_city.split(',') # 将每条行政区的信息转为list:‘北京’,’/beijing/‘,’海淀‘,’/haidian/‘
city_tianqi_15_url = tianqi_url + content_list[3] + '15' # 构建未来15天天气url
soup = get_html_soup(city_tianqi_15_url)
div_temp = soup.find('div', class_='inleft')
if (div_temp != None):
weather_list = soup.find('div', class_='inleft').find('ul', class_='weaul').find_all('li')
else:
return None
# print(weather_list)
for i in range(len(weather_list)):
li = weather_list[i]
# 提取时间:月日
str_temp = li.find_all('div')[0].get_text()
time_m_d = ''.join(re.findall(r'\d+', str_temp)) # ['07', '01']——月日0701
time_y_m_d = year_now + time_m_d
# 过渡时间(跨年)判断处理
if (time_m_d == '1231'):
y = int(year_now)
y += 1
year_now = str(y)
# 提取天气状况
str_temp = li.find_all('div')[2].get_text() # 多云转小雨21~35℃
weather_station = ''.join(re.findall(r'[\u4e00-\u9fa5]+', str_temp)) # 多云转小雨
# 提取温度(最低、最高)
temperature = re.findall(r'\d+', str_temp)
temperature_min = temperature[0]
temperature_max = temperature[1]
# 提取空气质量
air_quality = li.find_all('div')[3].span.get_text() # 多云转小雨21~35℃
# 提取风向、风力等级
str_temp = li.find_all('div')[4].get_text()
wind = ''.join(re.findall(r'^[\u4e00-\u9fa5]+', str_temp))
wind_scale = ''.join(re.findall(r'\d+', str_temp))
weather = provinces_city + ',' + time_y_m_d + ',' + weather_station + ',' + temperature_min + ',' + temperature_max + ',' + air_quality + ',' + wind + ',' + wind_scale
city_weather_list.append(weather)
return city_weather_list
(四)数据保存
- save_15_weather(weather_path, provinces_citys, year_now)
- weather_path: 保存地址,如 ‘citys_15_weather.csv’
- provinces_citys: 行政区域字符串list[string](格式:list【北京,/beijing/,海淀,/haidian/】)
- year_now: 当前年份 <class ‘str’>r如:‘2020’
'''
功能:保存未来15日天气
parameters:
weather_path:'citys_15_weather.csv'
provinces_citys:行政区域字符串list[string](格式:list【北京,/beijing/,海淀,/haidian/】)
year_now:<class 'str'>r如:'2020'
return:
None
'''
def save_15_weather(weather_path, provinces_citys, year_now):
with open(weather_path, 'w', encoding='utf-8') as f:
for i in range(len(provinces_citys)):
city_weather_list = get_15_weather(provinces_citys[i], year_now)
if (city_weather_list != None):
for li in city_weather_list:
f.write(li + '\n')
else:
continue
(五)主函数
if __name__ == '__main__':
year_now = str(datetime.datetime.now().year) # 获取当前时间(年)
path_15_weather = 'citys_15_weather.csv'#数据存放地址(根目录下)
# 获得行政区域列表
city_url = 'https://www.tianqi.com/chinacity.html' # 天气网站,用于爬取行政区
provinces_citys = get_admArea(city_url) # <class 'list'>:【北京,/beijing/,海淀,/haidian/】
# 保存未来15日天气数据
save_15_weather(path_15_weather, provinces_citys, year_now)