爬取中国城市天气--BeautifulSoup

视频学习

使用到的库:requests,BeautifulSoup,pyecharts
注意点:
1.使用enumerate函数,利用下标解决了爬取哈尔滨的时候,城市名,哈尔滨是在tr标签内的第二个td标签里,而其他城市名,都在第一个td标签内。
爬取中国城市天气--BeautifulSoup
其他城市:
爬取中国城市天气--BeautifulSoup
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()

效果图
爬取中国城市天气--BeautifulSoup