爬虫+数据分析,制作一个世界疫情人数增长动态柱状竞赛图

世界疫情的数据很多网站都有,这里我还是使用手机网易的疫情数据接口。

首先,切换ua,换成手机模式。百度搜索“网易 疫情”,

第一个就是。

 打开这个网址,点开开发者工具,刷新一下。就可以看到有这么几个,第一个请求,就是数据

但是这里我们要用的是世界疫情。所以,还得往下多看几眼。

这第一个请求里,会给你今天的世界疫情数据。但是我们想绘制的是随着时间变化,增长的数据竞赛柱状图。只有一天是不行的。

但是,这里有一个游泳的数据是,areaTree下面,每一个国家的id都有了。

后面用数据的请求接口,需要用到这个id。这里我就选7个国家,每个单独记下来就行,也没必要用request提取。

当然了,这里我也是用的python。毕竟第一次也不知道这几个国家的id。

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import re
import os
import time
import requests

plt.rcParams["font.family"] = "SimHei"

wk_dir = "数据分析"
data_dir = "数据分析/data"

headers = {
    'User-Agent': 'Mozilla/5.0 (Linux; Android 11) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.120 Mobile Safari/537.36',
    'Accept': '*/*',
    'Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2',
    'Origin': 'https://wp.m.163.com',
    'Connection': 'keep-alive',
    'Referer': 'https://wp.m.163.com/',
    'Sec-Fetch-Dest': 'empty',
    'Sec-Fetch-Mode': 'cors',
    'Sec-Fetch-Site': 'same-site',
    'TE': 'trailers',
}

params = (
    ('t', '326632088930'),
)

response = requests.get('https://c.m.163.com/ug/api/wuhan/app/data/list-total', headers=headers, params=params)

#NB. Original query string below. It seems impossible to parse and
#reproduce query strings 100% accurately so the one below is given
#in case the reproduced version is not "correct".
# response = requests.get('https://c.m.163.com/ug/api/wuhan/app/data/list-total?t=326632088930', headers=headers)

rj = response.json()
rj.keys()
data = rj['data']
data.keys()

areaTree = data['areaTree']

countryCode = [ x['id']  for x in areaTree]
countryName = [ x['name'] for x in areaTree]

dct_country_id = dict(zip(countryName, countryCode))

dct_country_id['美国']

 这里的代码,params,里面只有一个t, 这个t刚开始我以为是时间,但是也不知道这个是怎么构造的。反正就用这个,后面请求历史数据的时候,这个t也不需要改,没啥影响。

返回json格式的,我就依次提取 json数据里的 data→areaTree→各国的id

做成一个字典,这样通过字典就可以查询“美国”返回7,中国是0.

 然后点击“世界疫情”

 出现,各个国家的数据。

美国后面有“详情”,点击一下,看看这个请求时什么结构,

第二个请求,他的数据就是美国的数据,

 

我们看请求头。

 

 数据最后一行是今天的美国人数。

 

 这个请求头,是这个url

https://c.m.163.com/ug/api/wuhan/app/data/list-by-area-code?areaCode=7&t=1633273396571

 直接复制这个网址,到浏览器,可以看出,它就能返回给我们美国的数据。

 所以规律就是,替换掉 areaCode的数字,我们分别用几个国家的id,替换,轮番请求。就可以得到一个世界各国的疫情历史数据。

need_countries = ['中国', '美国', '英国', '伊朗', '西班牙', '韩国', '德国', '意大利', '印度']

need_countries

dct_allData = {}

for country in need_countries:
    country_id = dct_country_id[country]
    print(country, "*"*20, country_id)
    url = f"https://c.m.163.com/ug/api/wuhan/app/data/list-by-area-code?areaCode={country_id}&t=1633160447810"
    print(url)
    try:
        response = requests.get(url, headers = headers)
        time.sleep(3)
        rj = response.json()
        dct_allData[country] = rj['data']
        print("success")
    except:
        print("failed")

country_id

url

dct_allData

dct_allData.keys()

 这样就得到了9个国家的数据了。

 比如,美国的,都在字典 allData里


usa = dct_allData['美国']
usa['list']
list = usa['list']
len(list)

 先保存一下数据。

pd.to_pickle(dct_allData, os.path.join(data_dir, "allData疫情数据"))

后面在操作这个数据就可以了。

不需要爬虫了。

这里我们只需要两个数据就可以了。

就是

 date和confirm

其他都不需要。

dct_confirm = {}

for c in dct_allData.keys():
    confirm = [ x['total']['confirm'] for x in dct_allData[c]['list'] ]
    dct_confirm[c] = confirm

dct_confirm.keys()

len(dct_confirm['美国'])
len(dct_confirm['印度'])

每一个国家的数据,都可以做成一个dataframe

china_list = china['list']
china_date = [ x['date'] for x in china_list]
china_confirm = [ x['total']['confirm'] for x in china_list]

df_china = pd.DataFrame({
    'date':china_date,
    'confirm':china_confirm
})
df_china

这里要注意的是,不同国家,有的时间没有数据。date不是同样的。数据也不等长。

f_china.shape


usa_list = usa['list']
usa_date = [ x['date'] for x in usa_list]
usa_confirm = [ x['total']['confirm'] for x in usa_list]

df_usa = pd.DataFrame({
    'date':usa_date,
    'confirm':usa_confirm
})

df_usa.shape

 可以看出,中国有604个date有数据,美国只有589个。

这样在合并成一个大表的时候,就需要注意日期,有的是缺失值。

def get_data(key):
    len_key = len(df[key]['list'])
    print(len_key)
    data = []
    date = []
    for i in range(len_key):
        d = df[key]['list'][i]['total']['confirm']
        data.append(d)
        dt = df[key]['list'][i]['date']
        date.append(dt)

    return dict(zip(date, data))

dct_data = {}

for key in df.keys():
    dct_data[key] = get_data(key)

dct_data.keys()
pd.DataFrame(dct_data)

这里我们定义一个提取date和confirm的两个数据的函数,对每个国家执行这个函数,得到dct_data是一个大的字典。

直接用pandas生成这一个字典。

就可以得到一个大表。

 

 pandas还是很智能,会自动按照各个国家的date排序,把没有数值的弄成NAN,只保留一个date作为index


df_test = pd.DataFrame(dct_data)
df_test.shape
df_test.index

 

df_test2 = df_test.sort_index(ascending=True)
df_test2
df_test2.keys()

df_test2.columns = ['china', 'usa','uk',  'iran', 'spain', 'korea', 'germey', 'italian', 'india']
df_test2

把index按照时间顺序排序,把国家名字改成英文。

 

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值