zhaoxinhui

python爬虫(二十一) 中国天气网最低气温爬虫及可视化

 

网页如图所示

1、页面分析

 

 首先爬取华北地区

华北得url:http://www.weather.com.cn/textFC/hb.shtml

东北得url:http://www.weather.com.cn/textFC/db.shtml

依次很容易得到各个地区得url

 

 一个城市得情况在一个table里

 

 table里得第三个tr标签开始为这个城市得天气情况

2、华北城市数据爬取

import requests
from bs4 import  BeautifulSoup

def parse_page(url):
    headers={
        \'User-Agent\':"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36"
    }
    response=requests.get(url,headers=headers)
    text=response.content.decode(\'utf-8\')
    soup=BeautifulSoup(text,\'lxml\')
    conMidtab=soup.find(\'div\',class_=\'conMidtab\')
    tables=conMidtab.find_all(\'table\')
    for table in tables:
        trs=table.find_all(\'tr\')[2:]
        for tr in trs:

            tds=tr.find_all(\'td\')
            city_td=tds[0]
            city=list(city_td.stripped_strings)[0]
            temp_td=tds[-2]
            temp_min=list(temp_td.stripped_strings)[0]
            print({"city":city,"temp_min":temp_min})

def main():
    url="http://www.weather.com.cn/textFC/hb.shtml"
    parse_page(url)

if __name__ ==  \'__main__\':
    main()

华北地区的所有最低气温:

 

 

 3、所有城市最低气温爬取

在测试时可以发现,除了华北和港澳台地区,其他地区的城市信息例如:

 

 在华北地区的时候,第一个城市在第三个tr标签,城市的名字在tr标签下的第一个td标签,但是在这几个地区,第一个城市在第三个tr标签,而城市的名字在tr标签下的第二个td标签

这时需要加上几行代码

 city_td=tds[0]
            # 如果是第0个tr标签,城市就是第二个td标签,其余得都选第0个td标签
            if index==0:
                city_td = tds[1]

然后是港澳台,通过查看源代码可以看出来,港澳台里面是不规范的html代码,即有开始标签没有结束标签,如果按照上面的方式写,得到的是不正确的

 

 这时就不能用lxml解析器,需要用html5lib解析器

soup=BeautifulSoup(text,\'html5lib\')

如果没有安装,通过命令 pip install html5lib 安装

import requests
from bs4 import  BeautifulSoup

def parse_page(url):
    headers={
        \'User-Agent\':"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36"
    }
    response=requests.get(url,headers=headers)
    text=response.content.decode(\'utf-8\')
    soup=BeautifulSoup(text,\'html5lib\')
    conMidtab=soup.find(\'div\',class_=\'conMidtab\')
    tables=conMidtab.find_all(\'table\')
    for table in tables:
        trs=table.find_all(\'tr\')[2:]
        for index,tr in enumerate(trs):

            tds=tr.find_all(\'td\')

            city_td=tds[0]
            # 如果是第0个tr标签,城市就是第二个td标签,其余得都选第0个td标签
            if index==0:
                city_td = tds[1]
            city=list(city_td.stripped_strings)[0]
            temp_td=tds[-2]
            temp_min=list(temp_td.stripped_strings)[0]
            print({"city":city,"temp_min":temp_min})


def main():
    urls={
        \'http://www.weather.com.cn/textFC/hb.shtml\',
        \'http://www.weather.com.cn/textFC/db.shtml\',
        \'http://www.weather.com.cn/textFC/hd.shtml\',
        \'http://www.weather.com.cn/textFC/hz.shtml\',
        \'http://www.weather.com.cn/textFC/hn.shtml\',
        \'http://www.weather.com.cn/textFC/xb.shtml\',
        \'http://www.weather.com.cn/textFC/xn.shtml\',
        \'http://www.weather.com.cn/textFC/gat.shtml\'
    }
    for url in urls:
     parse_page(url)

if __name__ ==  \'__main__\':
    main()

 

 

 

 4、全国前十最低气温可视化

 

import requests
from bs4 import  BeautifulSoup
from pyecharts.charts import Bar

ALL_DATA=[]
def parse_page(url):
    headers={
        \'User-Agent\':"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36"
    }
    response=requests.get(url,headers=headers)
    text=response.content.decode(\'utf-8\')
    soup=BeautifulSoup(text,\'html5lib\')
    conMidtab=soup.find(\'div\',class_=\'conMidtab\')
    tables=conMidtab.find_all(\'table\')
    for table in tables:
        trs=table.find_all(\'tr\')[2:]
        for index,tr in enumerate(trs):

            tds=tr.find_all(\'td\')

            city_td=tds[0]
            # 如果是第0个tr标签,城市就是第二个td标签,其余得都选第0个td标签
            if index==0:
                city_td = tds[1]
            city=list(city_td.stripped_strings)[0]
            temp_td=tds[-2]
            temp_min=list(temp_td.stripped_strings)[0]
            ALL_DATA.append({"city":city,"temp_min":int(temp_min)})
            # print({"city":city,"temp_min":int(temp_min)})


def main():
    urls={
        \'http://www.weather.com.cn/textFC/hb.shtml\',
        \'http://www.weather.com.cn/textFC/db.shtml\',
        \'http://www.weather.com.cn/textFC/hd.shtml\',
        \'http://www.weather.com.cn/textFC/hz.shtml\',
        \'http://www.weather.com.cn/textFC/hn.shtml\',
        \'http://www.weather.com.cn/textFC/xb.shtml\',
        \'http://www.weather.com.cn/textFC/xn.shtml\',
        \'http://www.weather.com.cn/textFC/gat.shtml\'
    }
    for url in urls:
     parse_page(url)

     ALL_DATA.sort(key=lambda data:data[\'temp_min\'])
     data=ALL_DATA[0:10]
# 需要使用pyecharts
    cities=list(map(lambda x:x[\'city\'],data))
    temps=list(map(lambda x:x[\'temp_min\'],data))
    chart=Bar("中国气温排行榜")
    chart.add(\'\',cities,temps)
    chart.render(\'temperature.html\')

if __name__ ==  \'__main__\':
    main()

 

分类:

技术点:

相关文章: