利用Python爬取新冠肺炎疫情实时数据,Pyecharts画2019-nCoV疫情地图

前言

博客是2年前写的,中间有好多网友私信我获取源码及指出部分bug,感谢支持!
取不到数据的原因是数据接口发生较大变化,最近刚好有时间,所以重新整理了一下。

第一部分 网页分析

今天重新整理了一下,发现数据结构和之前的有所变化,把具体的操作步骤也说一下吧!打开网址推荐使用火狐浏览器,F12 进入开发者工具(刷新一下页面),如下,所有数据都可以通过接口获取:

  • 国内数据接口:
    https://api.inews.qq.com/newsqa/v1/query/inner/publish/modules/list?modules=
  • 各省历史数据接口:
    https://api.inews.qq.com/newsqa/v1/query/pubished/daily/list?adCode=
  • 国外数据接口:
    https://api.inews.qq.com/newsqa/v1/automation/modules/list?modules=

第二部分 数据获取

导入模块

import time 
import json
import requests
from datetime import datetime
import pandas as pd 
import numpy as np
import matplotlib.pyplot as plt 

pd.set_option('display.max_columns', None)
pd.set_option('display.max_rows', None) 
plt.rcParams['font.sans-serif']=['SimHei'] #用来正常显示中文标签
plt.rcParams['axes.unicode_minus']=False 
plt.style.use('ggplot')

抓取数据

获取步骤:

  • 先定义接口调用函数
  • 通过接口名获取数据,然后用pandas处理成Dataframe格式
def catch_data(api_name):
    url = 'https://api.inews.qq.com/newsqa/v1/query/inner/publish/modules/list?modules=' + api_name
    reponse = requests.get(url=url).json()
    return reponse
国内数据明细接口-chinaDayList
# 近60天国内现有数据汇总
chinadaylist = catch_data('chinaDayList')
chinadaylist = pd.DataFrame(chinadaylist['data']['chinaDayList'])
chinadaylist['date'] = pd.to_datetime(chinadaylist['y'].astype('str') + '.' + chinadaylist['date'])
chinadaylist = chinadaylist[['date','confirm','heal','dead','importedCase','nowConfirm','nowSevere','localConfirm']]
chinadaylist.columns = ['日期','累计确诊','累计治愈','累计死亡','累计境外输入','现有确诊','现有重症','本土现有确诊']
chinadaylist.tail()

在这里插入图片描述

国内每日新增数据接口-chinaDayAddListNew
#国内每日新增数据
chinanewadd = catch_data('chinaDayAddListNew')
chinanewadd = pd.DataFrame(chinanewadd['data']['chinaDayAddListNew'])
chinanewadd['date'] = pd.to_datetime(chinanewadd['y'].astype('str') + '.' + chinanewadd['date'])
chinanewadd = chinanewadd[['date','confirm','dead','heal','infect','importedCase','localConfirmadd','localinfectionadd']]
chinanewadd.columns = ['日期','新增确诊','新增死亡','新增治愈','新增无症状','新增境外','本土新增确诊','本土新增无症状']
chinanewadd.tail()

在这里插入图片描述

国内城市数据接口-diseaseh5Shelf

省份数据和城市数据处理方法:

  • 观察网页框架,省份数据在diseaseh5Shelf这个接口
  • diseaseh5Shelf返回一个字典,数据在areaTree,areaTree是一个list,list中第一个元素的children是一个存储省份数据的list
  • children共有34个元素,每一个元素是一个省份数,dict格式,包含name,adcode,total,today,children,前四个是省份总数据,children是省份城市明细
  • 城市数据和省份数据结构一样,但每一个children包含的城市数量不同用province_catch_data[i][‘children’]判断数量
#省份数据明细处理
province_data = pd.DataFrame()
#获取所有城市数据,第一步先处理省数据
province_catch_data = catch_data('diseaseh5Shelf')['data']['diseaseh5Shelf']['areaTree'][0]['children']
for i in range(len(province_catch_data)):
    province_total = province_catch_data[i]['total'] #省总数据
    province_total['name'] = province_catch_data[i]['name'] #省名
    province_total['adcode'] = province_catch_data[i]['adcode'] #省代码
    province_total['date'] = province_catch_data[i]['date'] #更新日期
    province_today = province_catch_data[i]['today'] #省当日数据
    province_today['name'] = province_catch_data[i]['name'] #省名
    province_total = pd.DataFrame(province_total,index=[i])
    province_today = pd.DataFrame(province_today,index=[i])
    province_today.rename({'confirm':'confirm_add'},inplace=True,axis=1) #today里面的confirm实际是每日新增
    merge_data = province_total.merge(province_today,how='left',on='name') #合并省总数据和当日数据
    province_data = pd.concat([province_data,merge_data]) #拼接省份数据
province_data = province_data[['name','adcode','date','confirm','provinceLocalConfirm','heal','dead','nowConfirm','confirm_add','local_confirm_add',
                               'wzz_add','abroad_confirm_add','dead_add','mediumRiskAreaNum','highRiskAreaNum','isUpdated']]
province_data.columns = ['省份','代码','日期','累计确诊','本土累计','累计治愈','累计死亡','现有确诊','当日新增','新增本土','新增无症状',
                         '新增境外','新增死亡','中风险数量','高风险数量','是否更新']
province_data = province_data.sort_values(by='累计确诊',ascending=False,ignore_index=True)
province_data.head()

在这里插入图片描述

df_city_data_total = pd.DataFrame()
for x in range(len(province_catch_data)):
    province_dict = province_catch_data[x]['children']
    province_name = province_catch_data[x]['name']
    df_city_data = pd.DataFrame()
    for i in range(len(province_dict)):
        city_total = province_dict[i]['total']
        city_total['province_name'] = province_name #省名
        city_total['name'] = province_dict[i]['name'] #市区名
        city_total['adcode'] = province_dict[i]['adcode'] #市区代码
        city_total['date'] = province_dict[i]['date'] #更新日期
        city_today = province_dict[i]['today'] #当日数据
        city_today['province_name'] = province_name #省名
        city_today['name'] = province_dict[i]['name'] #市区名
        city_total = pd.DataFrame(city_total,index=[i])
        city_today = pd.DataFrame(city_today,index=[i])
        city_today.rename({'confirm':'confirm_add'},inplace=True,axis=1) #today里面的confirm实际是每日新增
        merge_city = city_total.merge(city_today,how='left',on=['province_name','name'])
        df_city_data = pd.concat([df_city_data,merge_city])
    df_city_data_total = pd.concat([df_city_data_total,df_city_data])
df_city_data_total = df_city_data_total[['province_name','name','adcode','date','confirm','provinceLocalConfirm','heal','dead','nowConfirm','confirm_add','local_confirm_add',
                               'wzz_add','mediumRiskAreaNum','highRiskAreaNum']]
df_city_data_total.columns = ['省份','城市','代码','日期','累计确诊','本土累计','累计治愈','累计死亡','现有确诊','当日新增','新增本土','新增无症状','中风险数量','高风险数量']
df_city_data_total =df_city_data_total.sort_values(by='累计确诊',ascending=False,ignore_index=True)
df_city_data_total.head()
省份历史数据明细
#各省份历史数据明细,缺失台湾香港澳门,城市历史数据更换城市code即可
province_history_data = pd.DataFrame()
for code in province_data['代码']:
    if code != '':
        history_data = requests.get('https://api.inews.qq.com/newsqa/v1/query/pubished/daily/list?adCode=' + str(code)).json()['data']
        history_df = pd.DataFrame(history_data)
        history_df['date'] = pd.to_datetime(history_df['year'].astype('str') + '.' + history_df['date'])
        history_df_use = history_df[['date','province','confirm','dead','heal','wzz','newConfirm','newHeal','newDead','wzz_add']]
        history_df_use.columns = ['日期','省份','累计确诊','累计死亡','累计治愈','无症状','新增确诊','新增治愈','新增死亡','新增无症状']
        province_history_data = pd.concat([province_history_data,history_df_use])
        
province_history_data.shape
国外累计最新数据
#海外最新数据
aboard_data = requests.get('https://api.inews.qq.com/newsqa/v1/automation/modules/list?modules=WomAboard').json()['data']['WomAboard']
aboard_data = pd.DataFrame(aboard_data)
aboard_data_use = aboard_data[['pub_date','continent','name','confirm','dead','heal','nowConfirm','confirmAdd']]
aboard_data_use.columns = ['日期','大洲','国家','累计确诊','累计死亡','累计治愈','现有确诊','新增确诊']
aboard_data_use.head()

在这里插入图片描述

第三部分 数据可视化

导入pyecharts绘图相关包

from pyecharts.charts import * #导入所有图表
from pyecharts import options as opts
#导入pyecharts的主题(如果不使用可以跳过)
from pyecharts.globals import ThemeType
from pyecharts.commons.utils import JsCode
from pyecharts.globals import CurrentConfig, NotebookType
CurrentConfig.NOTEBOOK_TYPE = NotebookType.JUPYTER_NOTEBOOK

数据详情-Table

from pyecharts.components import Table
from pyecharts.options import ComponentTitleOpts
table = Table()
headers = list(chinadaylist.columns)
rows = chinadaylist.sort_values(by='日期',ascending=False).head(1).values
table.add(headers=headers,rows=rows)
table.set_global_opts(title_opts=ComponentTitleOpts(title="国内最新数据", 
                                                    subtitle="更新日期:" + chinadaylist['日期'].astype('str').max()))
table.render_notebook()

组合图(bar/line)

bar = Bar()
bar.add_xaxis(list(chinadaylist["日期"].astype('str')))
bar.add_yaxis(series_name ='累计确诊',y_axis=list(chinadaylist["累计确诊"]))
bar.add_yaxis(series_name ="现有确诊",y_axis=list(chinadaylist['现有确诊']))
bar.extend_axis(yaxis=opts.AxisOpts(name='治愈率',axislabel_opts=opts.LabelOpts(formatter="{value}%")))
bar.set_series_opts(label_opts=opts.LabelOpts(is_show=False))  #不显示数据标签
bar.set_global_opts(title_opts=opts.TitleOpts(title="国内累计确诊趋势",
                                              subtitle="数据来自腾讯疫情数据(含港澳台)", #添加副标题
                                              pos_left="center", #标题位置
                                              pos_top="top"),
                    legend_opts=opts.LegendOpts(pos_left="left"), #图例位置-左侧
                    xaxis_opts=opts.AxisOpts(type_="category",
                                             axislabel_opts=opts.AxisTickOpts()),
                    yaxis_opts=opts.AxisOpts(name="人数")
                    
                   )
line = Line()
line.add_xaxis(list(chinadaylist["日期"].astype('str')))
line.add_yaxis(series_name="治愈率(%)",
               y_axis=(chinadaylist['累计治愈']/chinadaylist['累计确诊']).round(decimals=3)*100,
               yaxis_index=1,
               symbol_size=3,
               is_smooth=True,
               label_opts=opts.LabelOpts(is_show=False),
               tooltip_opts=opts.TooltipOpts(formatter=JsCode("function (params) {return params.value+ '%'}"),
            is_show_content = True)
              )

bar.overlap(line) ##图形叠加
bar.render_notebook()

在这里插入图片描述

折线图美化

background_color_js = ("new echarts.graphic.LinearGradient(0, 0, 0,1, "
                       "[{offset: 0, color: '#99cccc'}, {offset: 1, color: '#00bfff'}], false)")

line1 = Line(init_opts=opts.InitOpts(theme=ThemeType.ROMA,bg_color=JsCode(background_color_js))) #设置主题&背景颜色

line1.add_xaxis(list(chinanewadd["日期"].astype('str')))  #添加x轴

line1.add_yaxis(series_name = "新增确诊",
                y_axis = list(chinanewadd["新增确诊"]), #增加Y轴数据
                is_smooth=True,#添加Y轴,平滑曲线
                areastyle_opts=opts.AreaStyleOpts(opacity=0.3), #区域阴影透明度
                is_symbol_show = True,
                label_opts=opts.LabelOpts(is_show=False),
                yaxis_index = 0 #指定y轴顺序
               ) #不显示标签

line1.add_yaxis(series_name = "新增本土",
                y_axis = list(chinanewadd["本土新增确诊"]),
                is_smooth=True,
                areastyle_opts=opts.AreaStyleOpts(opacity=0.3),
                is_symbol_show = True,#是否显示标记
#                 symbol = 'circle' #标记类型 'circle', 'rect', 'roundRect', 'triangle', 'diamond', 'pin', 'arrow', 'none'
                label_opts=opts.LabelOpts(is_show=False),
                yaxis_index = 1
               )
#增加副轴
line1.extend_axis(yaxis=opts.AxisOpts(
                        name="新增本土(人)",
                        name_location="end", #轴标题位置
                        type_="value",#轴类型
                        is_inverse=False, #逆序刻度值
                        axistick_opts=opts.AxisTickOpts(is_show=True),
                        splitline_opts=opts.SplitLineOpts(is_show=True)
                        )
                )
#设置图表格式
line1.set_global_opts(title_opts=opts.TitleOpts(title="国内每日新增趋势", #添加主标题
                                                subtitle="数据来自腾讯疫情数据(含港澳台)", #添加副标题
                                                subtitle_textstyle_opts = opts.TextStyleOpts(color='#000000'),
                                                pos_left="center", #标题位置
                                                pos_top="top"),
                    legend_opts=opts.LegendOpts(pos_left="40%",
                                                pos_top='10%'), #图例位置-左侧
                    xaxis_opts=opts.AxisOpts(type_="category",
                                             axislabel_opts=opts.AxisTickOpts()),
                    yaxis_opts=opts.AxisOpts(name="新增确诊(人)", 
                                             type_="value", 
#                                              max_=100000
                                            ),
                    datazoom_opts=opts.DataZoomOpts(type_= 'slider',
                                                    range_start=80 ,#横轴开始百分百
                                                    range_end=100) , #横轴结束百分比
                    toolbox_opts=opts.ToolboxOpts(is_show=True,  #显示工具窗口
                                                  orient='vertical', #垂直排列工具窗口
                                                  pos_left='95%',
                                                  pos_top='middle')
                     )

line1.render_notebook()

在这里插入图片描述

多tab轮播

map1= Map(init_opts=opts.InitOpts(width="900px",height="500px",bg_color=None))
map1.add(series_name = "累计确诊",
         data_pair = [list(z) for z in zip(province_data['省份'],province_data['累计确诊'])],
         maptype = "china",
         is_map_symbol_show=False)

map1.set_global_opts(title_opts=opts.TitleOpts(title="全国疫情地图-累计确诊",
                                               subtitle="更新日期:" + province_data['日期'].astype('str').max(),
                                               subtitle_textstyle_opts = opts.TextStyleOpts(color='#ffffff'),
                                               pos_left="center"),
                legend_opts=opts.LegendOpts(is_show=True, pos_top="40px", pos_left="30px"),
                visualmap_opts=opts.VisualMapOpts(is_piecewise=True,
                                                  range_text=['高', '低'],
                                                  pieces=[
                                                    {"min": 50000, "color": "#751d0d"},
                                                    {"min": 10000, "max": 49999, "color": "#ae2a23"},
                                                    {"min": 5000, "max": 9999, "color": "#d6564c"},
                                                    {"min": 1000, "max": 4999, "color": "#f19178"},
                                                    {"min": 500, "max": 999, "color": "#f7d3a6"},
                                                    {"min": 100, "max": 499, "color": "#fdf2d3"},
                                                    {"min": 0, "max": 99, "color": "#FFFFFF"}]),
                     toolbox_opts=opts.ToolboxOpts(is_show=True,  #显示工具窗口
                                                  orient='vertical', #垂直排列工具窗口
                                                  pos_left='95%',
                                                  pos_top='middle'),
            )


map2= Map(init_opts=opts.InitOpts(width="900px",height="500px",bg_color=None))
map2.add(series_name = "现有确诊",
         data_pair = [list(z) for z in zip(province_data['省份'],province_data['现有确诊'])],
         maptype = "china",
         is_map_symbol_show=False)

map2.set_global_opts(title_opts=opts.TitleOpts(title="全国疫情地图-现有确诊",
                                               subtitle="更新日期:" + province_data['日期'].astype('str').max(),
                                               subtitle_textstyle_opts = opts.TextStyleOpts(color='#ffffff'),
                                               pos_left="center"),
                legend_opts=opts.LegendOpts(is_show=True, pos_top="40px", pos_left="30px"),
                visualmap_opts=opts.VisualMapOpts(is_piecewise=True,
                                                  range_text=['高', '低'],
                                                  pieces=[
                                                    {"min": 10000, "color": "#751d0d"},
                                                    {"min": 1000, "max": 9999, "color": "#ae2a23"},
                                                    {"min": 500, "max": 999, "color": "#d6564c"},
                                                    {"min": 100, "max": 499, "color": "#f19178"},
                                                    {"min": 10, "max": 99, "color": "#f7d3a6"},
                                                    {"min": 1, "max": 9, "color": "#fdf2d3"},
                                                    {"min": 0, "max": 0, "color": "#FFFFFF"}]),
                     toolbox_opts=opts.ToolboxOpts(is_show=True,  #显示工具窗口
                                                  orient='vertical', #垂直排列工具窗口
                                                  pos_left='95%',
                                                  pos_top='middle'),
            )
##i添加选项卡tab
tab = Tab()
tab.add(map1, "累计确诊地图")
tab.add(map2, "现有确诊地图")

        
tab.render_notebook()

在这里插入图片描述

时间轴轮播-map


```python
##给日期排序
province_history_data['date_rank'] = province_history_data['日期'].rank(method='dense',ascending=True)
df_list = []
#取前15日数据,可任意变更
for i in range(1,15):
    df_list.append(province_history_data.loc[province_history_data['date_rank']==i])

tl = Timeline(init_opts=opts.InitOpts(theme=ThemeType.CHALK,width="900px", height="600px")) #时间轴

for idx in range(len(df_list)):#循环给时间轴增加图形
    provinces = []
    confirm_value = []
    date = df_list[idx]['日期'].astype('str').unique()[0]
    for item_pv in df_list[idx]['省份']:
        provinces.append(item_pv)
    for item_pc in df_list[idx]['累计确诊']:
        confirm_value.append(item_pc)
    zipped = zip(provinces, confirm_value)
    f_map = Map(init_opts=opts.InitOpts(width="800",height="500px"))
    f_map.add(series_name="确诊数量",
                  data_pair=[list(z) for z in zipped],
                  maptype="china",
                  is_map_symbol_show=False)
    f_map.set_global_opts(title_opts=opts.TitleOpts(title="全国疫情地图-累计确诊",
                                               subtitle="更新日期:" + date,
                                               subtitle_textstyle_opts = opts.TextStyleOpts(color='#ffffff'),
                                               pos_left="center"),
                legend_opts=opts.LegendOpts(is_show=False, pos_top="40px", pos_left="30px"),
                visualmap_opts=opts.VisualMapOpts(is_piecewise=True,
                                                  range_text=['高', '低'],
                                                  pieces=[
                                                    {"min": 1000, "color": "#CC0033"},
                                                    {"min": 200, "max": 999, "color": "#FF4500"},
                                                    {"min": 50, "max": 199, "color": "#FF8C00"},
                                                    {"min": 1, "max": 49, "color": "#FFDAB9"},
                                                    {"min": 0, "max": 0, "color": "#F5F5F5"}],
                                                  textstyle_opts = opts.TextStyleOpts(color='#ffffff'),
                                                  pos_bottom='15%',
                                                  pos_left='5%'
                                                 )
            )
        
    tl.add(f_map, "{}".format(date)) #添加图形
tl.add_schema(is_timeline_show=True,  # 是否显示
              play_interval=1200,  # 播放间
              symbol=None,  # 图标
              is_loop_play=True , # 循环播放
              is_auto_play = True
             )
tl.render_notebook()

在这里插入图片描述

  • 128
    点赞
  • 461
    收藏
  • 打赏
    打赏
  • 64
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:游动-白 设计师:我叫白小胖 返回首页
评论 64

打赏作者

Hakuna_Matata_001

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值