爬取中国城市天气--BeautifulSoup
视频学习
使用到的库:requests,BeautifulSoup,pyecharts
注意点:
1.使用enumerate函数,利用下标解决了爬取哈尔滨的时候,城市名,哈尔滨是在tr标签内的第二个td标签里,而其他城市名,都在第一个td标签内。
其他城市:
2.使用了html5lib解析器,利用其最强的容错率,解决了爬取港澳台地区时,由于源代码不规范,缺少
而只有
全代码:
#--*encoding:utf-8*--
import requests
from bs4 import BeautifulSoup
import pyecharts
"""
目标:
获得华北地区最热的前十名城市,并可视化打印出柱体
页面分析:
1.class="hanml"下的每个div,attrs={"class":"conMidtab"}标签表示一个周里每一天的天气信息
2.各个省/直辖市的天气信息在div,class_="conMidtab"下的div,class_="conMidtab2"中
3.各个省的各个城市天气信息在div,class="conMidtab2"下的table里的tr标签内,其中前面两个tr标签是无用的
4.我们需要各个各个城市的气温,气温在tr标签下td标签内
华北地区天气和其他东北,西北等地区页面结构一致,只需更改地区url即可爬取。
"""
def get_htmlpage(url):
headers={"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36"}
res=requests.get(url,headers=headers)
text=res.content.decode("utf-8","ignore")
#lxml容错率弱,爬港澳台的时候,源代码中标签少了</table>,从而会出错
#soup=BeautifulSoup(text,"lxml")
#html5lib容错率最高
soup=BeautifulSoup(text,"html5lib")
return soup
def parse_page(soup,min_tmps):
#找到第一个conMidtab,所以用的find,而非find_all
conMidtab=soup.find("div",attrs={"class":"conMidtab"})
tables=conMidtab.find_all("table")
for table in tables:
#取第三个tr标签开始,前面两个无用
trs=table.find_all("tr")[2:]
for index,tr in enumerate(trs):
tds=tr.find_all("td")
td_city = tds[0]
#tr==0的时候,哈尔滨在tds[1]上,其他城市在tds[0]上
if index==0:
td_city=tds[1]
#用stripped_strings取字符串,返回生成器,用列表转换,取[0]
city=list(td_city.stripped_strings)[0]
td_temp=list(tds[-2].stripped_strings)[0]
#td_temp这里的int不可少,用于后面提取td_temp进行排序
min_tmp={"city":city ,"tmp":int(td_temp)}
min_tmps.append(min_tmp)
"""
另一种:
td_city=td_city.stripped_strings
for city in td_city:
print(city)
"""
#提取未排名的温度信息列表中的(tmp)温度值
# def sorts(min_tmps):
# min_tmp=min_tmps["tmp"]
# return min_tmp
def main():
areas = ["hb", "db", "hd", "hz", "hn", "xb", "xn","gat"]
#城市最低温度信息(未排序)
min_tmps=[]
for area in areas:
url = "http://www.weather.com.cn/textFC/{every_area}.shtml".format(every_area=area)
soup = get_htmlpage(url)
parse_page(soup,min_tmps)
#方法一:列表中是字典的时候。用自定义函数sorts提取字典中tmp值,再用列表的sort方法进行排序
#min_tmps.sort(key=sorts)
#方法2:使用lambda函数,免去自定义一个sort函数
min_tmps.sort(key=lambda min_tmps:min_tmps["tmp"])
#获取前10最冷的城市
min_tmps=min_tmps[0:10]
#取城市,
cities=list(map(lambda tmp_city:tmp_city["city"],min_tmps))
#取温度
tmps=list(map(lambda tmp:tmp["tmp"],min_tmps))
chart=pyecharts.Bar("中国城市天气最低排行榜")
#给横坐标 纵坐标
chart.add("",cities,tmps)
#渲染
chart.render("Temperature.html")
if __name__=="__main__":
main()
效果图