Python疫情数据爬取与可视化展示

使用Python爬取腾讯新闻疫情数据,并使用pyecharts可视化,绘制国内、国际日增长人数地图,matplotlib绘制方寸图。

随笔记录所的所学,此博客为我记录文章所用,发布到此,仅供网友阅读参考。作者:北山啦

写在前面:这个已经不是什么新鲜的话题了,所以请大佬勿喷

文章目录

  • 疫情数据爬取与可视化展示
  • 1. 疫情数据抓取
  • 2. 初步分析
  • 3. 数据处理
  • 3.1 国内各省疫情数据提取
  • 3.2 国际疫情数据提取
  • 3.3 数据整合
  • 4. 可视化展示
  • 4.1 国内疫情态势可视化
  • 4.2 国际疫情态势可视化
  • 4.3 国内疫情方寸间
  • 4.4 国际疫情方寸间
  • 参考链接
  • 导入相关模块

    import time
    import json
    import requests
    from datetime import datetime
    import pandas as pd
    import numpy as np
    

    1. 疫情数据抓取

    通过腾讯新闻公布的数据进行爬取

    网址:https://news.qq.com/zt2020/page/feiyan.htm#/

    对于静态网页,我们只需要把网页地址栏中的url传到get请求中就可以轻松地获取到网页的数据。 对于动态网页抓取的关键是先分析网页数据获取和跳转的逻辑,再去写代码 。

    右击检查,选择Network,Ctrl+R即可

    记得安装快速第三方库

    pip3 install -i https://pypi.tuna.tsinghua.edu.cn/simple 包名
    

    快速下载模块

    # 定义抓取数据函数:https://beishan.blog.csdn.net/
    def Domestic():
        url = 'https://view.inews.qq.com/g2/getOnsInfo?name=disease_h5'
        reponse = requests.get(url=url).json()
        data = json.loads(reponse['data'])
        return data
    
    
    def Oversea():
        url = 'https://view.inews.qq.com/g2/getOnsInfo?name=disease_foreign'
        reponse = requests.get(url=url).json()
        data = json.loads(reponse['data'])
        return data
    
    
    domestic = Domestic()
    oversea = Oversea()
    
    print(domestic.keys())
    print(oversea.keys())
    
    dict_keys(['lastUpdateTime', 'chinaTotal', 'chinaAdd', 'isShowAdd', 'showAddSwitch', 'areaTree'])
    dict_keys(['foreignList', 'globalStatis', 'globalDailyHistory', 'importStatis', 'countryAddConfirmRankList', 'countryConfirmWeekCompareRankList', 'continentStatis'])
    

    2. 初步分析

    提取各地区数据明细

    # 提取各地区数据明细
    areaTree = domestic['areaTree']
    # 查看并分析具体数据
    areaTree
    

    提取国外地区数据明细

    # 提取国外地区数据明细
    foreignList = oversea['foreignList']
    # 查看并分析具体数据
    foreignList
    

    就可以看到在json数据存储的结构了

    3. 数据处理

    3.1 国内各省疫情数据提取

    # Adresss:https://beishan.blog.csdn.net/
    china_data = areaTree[0]['children'] 
    china_list = []
    for a in range(len(china_data)):
        province = china_data[a]['name']  
        confirm = china_data[a]['total']['confirm'] 
        heal = china_data[a]['total']['heal']  
        dead = china_data[a]['total']['dead']  
        nowConfirm = confirm - heal - dead 
        china_dict = {} 
        china_dict['province'] = province  
        china_dict['nowConfirm'] = nowConfirm 
        china_list.append(china_dict) 
    
    china_data = pd.DataFrame(china_list) 
    china_data.to_excel("国内疫情.xlsx", index=False) #存储为EXCEL文件
    china_data.head()
    
    province nowConfirm
    0 香港 323
    1 上海 40
    2 四川 34
    3 台湾 30
    4 广东 29

    3.2 国际疫情数据提取

    world_data = foreignList  
    world_list = []  
    
    for a in range(len(world_data)):
        # 提取数据
        country = world_data[a]['name']
        nowConfirm = world_data[a]['nowConfirm']  
        confirm = world_data[a]['confirm']
        dead = world_data[a]['dead']  
        heal = world_data[a]['heal'] 
        # 存放数据
        world_dict = {}
        world_dict['country'] = country
        world_dict['nowConfirm'] = nowConfirm
        world_dict['confirm'] = confirm
        world_dict['dead'] = dead
        world_dict['heal'] = heal
        world_list.append(world_dict)
    
    world_data = pd.DataFrame(world_list)
    world_data.to_excel("国外疫情.xlsx", index=False)
    world_data.head()
    
    country nowConfirm confirm dead heal
    0 美国 7282611 30358880 552470 22523799
    1 西班牙 193976 3212332 72910 2945446
    2 法国 2166003 2405255 57671 181581
    3 秘鲁 111940 422183 19408 290835
    4 英国 90011 104145 13759 375

    3.3 数据整合

    将国内数据和海外数据合并

    查询数据中是否含有中国疫情数据

    world_data.loc[world_data['country'] == "中国"]
    
    country nowConfirm confirm dead heal

    从新增areaTree中提取中国数据,并添加至world_data

    confirm = areaTree[0]['total']['confirm']  # 提取中国累计确诊数据
    heal = areaTree[0]['total']['heal']  # 提取中国累计治愈数据
    dead = areaTree[0]['total']['dead']  # 提取中国累计死亡数据
    nowConfirm = confirm - heal - dead  # 计算中国现有确诊数量
    
    world_data = world_data.append(
        {
            'country': "中国",
            'nowConfirm': nowConfirm,
            'confirm': confirm,
            'heal': heal,
            'dead': dead
        },
        ignore_index=True)
    

    再次查询数据中是否含有中国疫情数据

    world_data.loc[world_data['country'] == "中国"]
    
    country nowConfirm confirm dead heal
    161 中国 518 102479 4849 97112

    4. 可视化展示

    4.1 国内疫情态势可视化

    导入pyecharts相关库

    快速掌握数据可视化工具pyecharts

    import pyecharts.options as opts
    from pyecharts.charts import Map
    from pyecharts.globals import CurrentConfig, NotebookType
    CurrentConfig.NOTEBOOK_TYPE = NotebookType.JUPYTER_LAB
    

    国内各地区现有确诊人数地图

    m = Map()
    m.add("", [
        list(z)
        for z in zip(list(china_data["province"]), list(china_data["nowConfirm"]))
    ],
          maptype="china",
          is_map_symbol_show=False)
    m.set_global_opts(
        title_opts=opts.TitleOpts(title="COVID-19中国现有地区现有确诊人数地图"),
        visualmap_opts=opts.VisualMapOpts(
            is_piecewise=True,
            pieces=[
                {
                    "min": 5000,
                    "label": '>5000',
                    "color": "#893448"
                },  # 不指定 max,表示 max 为无限大
                {
                    "min": 1000,
                    "max": 4999,
                    "label": '1000-4999',
                    "color": "#ff585e"
                },
                {
                    "min": 500,
                    "max": 999,
                    "label": '500-1000',
                    "color": "#fb8146"
                },
                {
                    "min": 101,
                    "max": 499,
                    "label": '101-499',
                    "color": "#ffA500"
                },
                {
                    "min": 10,
                    "max": 100,
                    "label": '10-100',
                    "color": "#ffb248"
                },
                {
                    "min": 1,
                    "max": 9,
                    "label": '1-9',
                    "color": "#fff2d1"
                },
                {
                    "max": 1,
                    "label": '0',
                    "color": "#ffffff"
                }
            ]))
    m.render_notebook()
    

    4.2 国际疫情态势可视化

    将各国的中文名称转换成英文名称,使用pandas中的merge方法

    pd.merge( left, right, how=‘inner’, on=None, left_on=None, right_on=None, left_index=False, right_index=False, sort=False, suffixes=(‘_x’, ‘_y’), copy=True, indicator=False, validate=None,)

    how: One of ‘left’, ‘right’, ‘outer’, ‘inner’. 默认inner。inner是取交集,outer取并集

    这里需要使用到,国家中英文对照表.xlsx。提取码: u1mc
    百度网盘自取提取码: u1mc

    world_name = pd.read_excel("国家中英文对照表.xlsx")
    world_data_t = pd.merge(world_data,
                            world_name,
                            left_on="country",
                            right_on="中文",
                            how="inner")
    
    world_data_t
    
    country nowConfirm confirm dead heal 英文 中文
    0 美国 7282611 30358880 552470 22523799 United States 美国
    1 西班牙 193976 3212332 72910 2945446 Spain 西班牙
    2 法国 2166003 2405255 57671 181581 France 法国
    3 秘鲁 111940 422183 19408 290835 Peru 秘鲁
    4 英国 90011 104145 13759 375 United Kingdom 英国
    164 伯利兹 2 2 0 0 Belize 伯利兹
    165 东帝汶 1 1 0 0 Timor-Leste 东帝汶
    166 东帝汶 1 1 0 0 East Timor 东帝汶
    167 巴布亚新几内亚 1 1 0 0 Papua New Guinea 巴布亚新几内亚
    168 中国 518 102479 4849 97112 China 中国

    169 rows × 7 columns

    世界各国现有确诊人数地图

    m2 = Map()
    m2.add("", [
        list(z)
        for z in zip(list(world_data_t["英文"]), list(world_data_t["nowConfirm"]))
    ],
           maptype="world",
           is_map_symbol_show=False)
    m2.set_global_opts(title_opts=opts.TitleOpts(title="COVID-19世界各国现有确诊人数地图"),
                       visualmap_opts=opts.VisualMapOpts(is_piecewise=True,
                                                         pieces=[{
                                                             "min": 5000,
                                                             "label": '>5000',
                                                             "color": "#893448"
                                                         }, {
                                                             "min": 1000,
                                                             "max": 4999,
                                                             "label": '1000-4999',
                                                             "color": "#ff585e"
                                                         }, {
                                                             "min": 500,
                                                             "max": 999,
                                                             "label": '500-1000',
                                                             "color": "#fb8146"
                                                         }, {
                                                             "min": 101,
                                                             "max": 499,
                                                             "label": '101-499',
                                                             "color": "#ffA500"
                                                         }, {
                                                             "min": 10,
                                                             "max": 100,
                                                             "label": '10-100',
                                                             "color": "#ffb248"
                                                         }, {
                                                             "min": 0,
                                                             "max": 9,
                                                             "label": '0-9',
                                                             "color": "#fff2d1"
                                                         }]))
    """取消显示国家名称"""
    m2.set_series_opts(label_opts=opts.LabelOpts(is_show=False))
    m2.render_notebook()
    

    4.3 国内疫情方寸间

    单独取出中国疫情数据

    # 单独取出中国疫情数据
    China_data = world_data.loc[world_data['country'] == "中国"]
    
    # 使索引从0开始递增
    China_data.reset_index(drop=True, inplace=True)
    
    China_data
    
    country nowConfirm confirm dead heal
    0 中国 518 102479 4849 97112

    提取China_data的累计确诊、累计治愈与累计死亡数据

    # 提取China_data的累计确诊、累计治愈与累计死亡数据
    # data.at[n,'name']代表根据行索引和列名,获取对应元素的值
    w_confirm = China_data.at[0, 'confirm']
    w_heal = China_data.at[0, 'heal']
    w_dead = China_data.at[0, 'dead']
    

    导入matplotlib相关库

    import matplotlib.pyplot as plt
    import matplotlib.patches as patches
    

    构建国内疫情方寸间图示

    # -*- coding: utf-8 -*-
    %matplotlib inline
    
    fig1 = plt.figure()
    
    ax1 = fig1.add_subplot(111, aspect='equal', facecolor='#fafaf0')
    ax1.set_xlim(-w_confirm / 2, w_confirm / 2)
    ax1.set_ylim(-w_confirm / 2, w_confirm / 2)
    ax1.spines['top'].set_color('none')
    ax1.spines['right'].set_color('none')
    ax1.spines['bottom'].set_position(('data', 0))
    ax1.spines['left'].set_position(('data', 0))
    ax1.set_xticks([])
    ax1.set_yticks([])
    
    p0 = patches.Rectangle((-w_confirm / 2, -w_confirm / 2),
                           width=w_confirm,
                           height=w_confirm,
                           facecolor='#29648c',
                           label='confirm')
    p1 = patches.Rectangle((-w_heal / 2, -w_heal / 2),
                           width=w_heal,
                           height=w_heal,
                           facecolor='#69c864',
                           label='heal')
    p2 = patches.Rectangle((-w_dead / 2, -w_dead / 2),
                           width=w_dead,
                           height=w_dead,
                           facecolor='#000000',
                           label='dead')
    
    plt.gca().add_patch(p0)
    plt.gca().add_patch(p1)
    plt.gca().add_patch(p2)
    plt.title('COVID-19 Square - China', fontdict={'size': 20})
    plt.legend(loc='best')
    plt.show()
    

    4.4 国际疫情方寸间

    重新排序数据

    world_data.sort_values("confirm", ascending=False, inplace=True)
    world_data.reset_index(drop=True, inplace=True)
    world_data
    
    country nowConfirm confirm dead heal
    0 美国 7282611 30358880 552470 22523799
    1 西班牙 193976 3212332 72910 2945446
    2 法国 2166003 2405255 57671 181581
    3 秘鲁 111940 422183 19408 290835
    4 英国 90011 104145 13759 375
    157 利比里亚 3 3 0 0
    158 几内亚比绍 2 2 0 0
    159 伯利兹 2 2 0 0
    160 东帝汶 1 1 0 0
    161 巴布亚新几内亚 1 1 0 0

    162 rows × 5 columns

    构建国际疫情方寸间图示

    # -*- coding: utf-8 -*-
    plt.rcParams['font.sans-serif'] = [u'SimHei']
    plt.rcParams['axes.unicode_minus'] = False
    fig1 = plt.figure(figsize=(25, 25))
    for a in range(20):
    
        w_confirm = world_data.at[a, 'confirm']
        w_heal = world_data.at[a, 'heal']
        w_dead = world_data.at[a, 'dead']
        ax1 = fig1.add_subplot(20 / 4,
                               4,
                               a + 1,
                               aspect='equal',
                               facecolor='#fafaf0')
        ax1.set_xlim(-w_confirm / 2, w_confirm / 2)
        ax1.set_ylim(-w_confirm / 2, w_confirm / 2)
    
        ax1.spines['top'].set_color('none')
        ax1.spines['right'].set_color('none')
        ax1.spines['bottom'].set_position(('data', 0))
        ax1.spines['left'].set_position(('data', 0))
        ax1.set_xticks([])
        ax1.set_yticks([])
        p0 = patches.Rectangle((-w_confirm / 2, -w_confirm / 2),
                               width=w_confirm,
                               height=w_confirm,
                               alpha=w_confirm / 90000,
                               facecolor='#29648c',
                               label='confirm')
        p1 = patches.Rectangle((-w_heal / 2, -w_heal / 2),
                               width=w_heal,
                               height=w_heal,
                               alpha=1,
                               facecolor='#69c864',
                               label='heal')
        p2 = patches.Rectangle((-w_dead / 2, -w_dead / 2),
                               width=w_dead,
                               height=w_dead,
                               alpha=1,
                               facecolor='black',
                               label='dead')
        plt.gca().add_patch(p0)
        plt.gca().add_patch(p1)
        plt.gca().add_patch(p2)
    
    
        plt.title(world_data.at[a, 'country'], fontdict={'size': 20})
    
    
        plt.legend(loc='best')
    
    plt.show()
    


    这样就可以清楚的看到各个国家新冠确诊人数、治愈和死亡人数的关系了

    推荐阅读

    1. 冰冰B站视频弹幕爬取原理解析
    2. Python建立时间序列ARIMA模型实战案例
    3. 使用xpath爬取数据
    4. jupyter notebook使用
    5. BeautifulSoup爬取豆瓣电影Top250
    6. 一篇文章带你掌握requests模块
    7. Python网络爬虫基础–BeautifulSoup

    参考链接

    1. 腾讯疫情动态
    2. Python 制作全国疫情地图
    3. 利用Python实现新冠疫情数据可视化
    4. 欢迎关注

    到这里就结束了,如果对你有帮助,欢迎点赞关注评论,你的点赞对我很重要。

    来源:北山啦

    物联沃分享整理
    物联沃-IOTWORD物联网 » Python疫情数据爬取与可视化展示

    发表评论