zoukankan      html  css  js  c++  java
  • Python告诉你今天最冷的地方在哪里

    抓取目标

    这次我们的目标是爬取全国最冷的 10 座城市。

    首先打开目标网站 - 中国天气网。

    http://www.weather.com.cn/textFC/hb.shtml

     
    image

    我们要爬取全国所有城市的最低温度,然后获取温度最低的 10 个城市,并绘制成柱状图。

    准备工作

    由于爬取的数据少,考虑使用「 美味汤 - beautiful soup 」的方式来爬取。

    另外,最后需要根据数据生成柱状图,需要安装requests、bs4、html5lib、pandas、matplotlib、seaborn等库,不然控制台会报错。

    注意:一般爬虫使用 lxml 去解析,但是由于中国天气网的「 港澳台 」页面源码中存在很多标签没有正确关闭,因此使用 html5lib 的方式去解析数据。

     
     

    爬取思路

    首先,我们可以看到全国分为华北、东北、华东、华中、华南、西北、西南、港澳台,8 个区域来展示天气数据。

    # 一共8个区域,包含:华北、东北、华东、华中、华南、西北、西南、港澳台
    # 华北
    url_hb = 'http://www.weather.com.cn/textFC/hb.shtml'
    # 东北
    url_db = 'http://www.weather.com.cn/textFC/db.shtml'
    # 华东
    url_hd = 'http://www.weather.com.cn/textFC/hd.shtml'
    # 华中
    url_hz = 'http://www.weather.com.cn/textFC/hz.shtml'
    # 华南
    url_hn = 'http://www.weather.com.cn/textFC/hn.shtml'
    # 西北
    url_xb = 'http://www.weather.com.cn/textFC/xb.shtml'
    # 西南
    url_xn = 'http://www.weather.com.cn/textFC/xn.shtml'
    # 港澳台【比较特殊】
    url_gat = 'http://www.weather.com.cn/textFC/gat.shtml'
    

    我们首先需要去获取每一个区域下所有城市的天气数据,然后再对数据进行整理排序,写入到图形文件中。

    代码实现

    首先爬取「 华北地区 」城市的天气数据。

     
     

    可以获取到下面的规律:

    所有的「 class="conMidtab" 」的 6 个 div 保存着华北地区所有城市,包含今天以内未来一周的天气数据。

    每一个「 class="conMidtab2" 」的 div 代表了一个省份的天气信息。

    省份下面的城市天气数据,都包含 table 标签下。从第 3 个 tr 标签开始,是每一个城市的天气数据。

     
    接下来,循环全国 8 个区域的列表,获取所有城市的名称和温度数据。

    然后拿到所有城市和温度的列表数据后,就可以对数据按温度进行「 升序 」排列。

    最后将数据写入到柱状图中,就能很直观的查看到今天温度最低的 10 个城市。

    #!/usr/bin/env python
    #encoding: utf-8
    
    import requests
    from bs4 import BeautifulSoup
    import time
    import pandas as pd
    import seaborn as sns
    import matplotlib.pyplot as plt
    plt.rc("font",family="SimHei",size="10")  #用于解决不能显示中文的问题
    plt.rcParams['axes.unicode_minus']=False #用于解决不能显示负号的问题
    
    sns.set(style='whitegrid')
    plt.rc("font",family="SimHei",size="10")
    
    # 一共8个区域,包含:华北、东北、华东、华中、华南、西北、西南、港澳台
    # 华北
    url_hb = 'http://www.weather.com.cn/textFC/hb.shtml'
    # 东北
    url_db = 'http://www.weather.com.cn/textFC/db.shtml'
    # 华东
    url_hd = 'http://www.weather.com.cn/textFC/hd.shtml'
    # 华中
    url_hz = 'http://www.weather.com.cn/textFC/hz.shtml'
    # 华南
    url_hn = 'http://www.weather.com.cn/textFC/hn.shtml'
    # 西北
    url_xb = 'http://www.weather.com.cn/textFC/xb.shtml'
    # 西南
    url_xn = 'http://www.weather.com.cn/textFC/xn.shtml'
    # 港澳台【比较特殊】
    url_gat = 'http://www.weather.com.cn/textFC/gat.shtml'
    
    url_areas = [url_hb, url_db, url_hd, url_hz, url_hn, url_xb, url_xn, url_gat]
    
    #打开chrome输入【chrome://version/】获取用户代理
    HEADERS = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36',
        'Referer': 'http://www.weather.com.cn/textFC/hb.shtml'
    }
    
    # 数据【城市+最低温度】列表
    ALL_DATA = []
    
    def parse_page(url):
        """
            解析一个区域:华北、东北、华东等
            :param url:
            :return:
        """
        response = requests.get(url, headers=HEADERS)
        # 1.获取页面的原始html数据
        text = response.content.decode('utf-8')
        # 注意:港澳台中香港的table标签没有正确的关闭,使用lxml解析器不能正确解析。需要使用html5lib【容错性强】去自动补全代码,然后进行解析
        soup = BeautifulSoup(text, 'html5lib')
        # 2.查找class='conMidtab'的div,获取所有一个地区下的所有城市天气数据
        #find只返回第一个匹配到的对象
        div_conMidtab = soup.find('div', class_='conMidtab')
        # 3.获取所有的table子Tag【天气信息都保存在table标签下面】
        #find_all返回所有匹配到的结果
        tables = div_conMidtab.find_all('table')
        # 4.遍历片区下面的省份
        for table in tables:
            # 4.1过滤掉表头的两个tr数据
            trs = table.find_all('tr')[2:]
    
            # 5.遍历省份下面的市区
            #enumerate用于将一个可遍历的数据对象(如列表、元组或字符串等)组合为一个索引序列,同时列出数据和数据下标
            for index, tr in enumerate(trs):
                tds = tr.find_all('td')
                # 5.1 城市名称【第 1 个td标签】
                # 注意:一个省份第一个城市取第 2 个td标签;其余城市取第 1 个td标签
                city_td = tds[1] if index == 0 else tds[0]
                #stripped_strings用来获取目标路径下所有的子孙非标签字符串,会自动去掉空白字符串,返回的是一个生成器
                city = list(city_td.stripped_strings)[0]
                # 5.2 最低气温【倒数第 2 个td标签】
                temp_low_td = tds[-2]
                temp_low = list(temp_low_td.stripped_strings)[0]
                ALL_DATA.append({"城市": city, "温度": int(temp_low)})
    
    def spider():
        for index, url in enumerate(url_areas):
            print('开始爬取第{}个区域'.format(index + 1))
            parse_page(url)
            time.sleep(1)
    
    def analysis_data():
        """
            分析爬下来的数据
            :return:
            """
        # 1.默认的排序方式是升序【通过最低气温进行排序】
        ALL_DATA.sort(key=lambda data: data['温度'])
        # 2.获取前面10条数据
        top_10 = ALL_DATA[:10]
        return top_10
    
    def show_with_chart(top_10):
        """
            把最低的十个城市和温度生成柱状图
            :param top_10:
            :return:
            """
        # 1.获取城市列表
        # map接收一个函数f和一个list,并通过把函数f依次作用在list的每个元素上
        citys = list(map(lambda item: item['城市'], top_10))
        # 2.最低温度列表
        temp_lows = list(map(lambda item: item['温度'], top_10))
        print(citys,temp_lows)
    
        data=pd.DataFrame(top_10)
        sns.barplot(x='城市', y='温度', data=data)
    
        #3.生成图片并写入到文件中
        plt.savefig(r'd:1.jpg')
        #在pycharm中显示图片
        plt.show()
    
    if __name__ == '__main__':
        # 1.爬取数据
        spider()
        # 2.分析数据
        top_10 = analysis_data()
        print(top_10)
        # 3.使用seaborn生成柱状图
        show_with_chart(top_10)
  • 相关阅读:
    Optimal Milking
    Alice's Chance
    The Perfect Stall
    项目范围管理
    计算机网络总结 第六章 网络层
    计算机网络总结 第一章 计算机网络概论
    Http与url
    javaScript期末复习基础
    计算机网络各层涉及协议
    javaScript_canvas 面向对象实现
  • 原文地址:https://www.cnblogs.com/xiaohuhu/p/12119156.html
Copyright © 2011-2022 走看看