[练习] 获取新冠肺炎疫情数据

2020-02-16  本文已影响0人  張貳龍

一、前言

前一段时间通过手动摘录国家卫健委数据,及clone GitHub数据仓库的数据,简单做了一个Tableau的数据可视化(链接)。但是由于有手动操作的部分,稍显不便,所以便在网上搜索找到了使用Python获取web数据的方法,自己上手操作练习一下。

二、获取web数据

打开网址:https://news.qq.com/zt2020/page/feiyan.htm ,可以看到如下的界面:

访问界面

按下F12,然后刷新网页,在Network页搜索网页上的一个数字,比如57444,找到两项,可以在Headers下看到各自的Request URL(见下图),分别在浏览器的地址栏打开查看其中的内容。

F12

可以看到jmap.212.3.js和疫情数据关联不大,猜测可能多为地理坐标等信息,而getOnsInfo里面应该就是我们要找的疫情数据了,下面通过Python的request库获取数据。

>>> import requests
>>> import json
>>> url = 'https://view.inews.qq.com/g2/getOnsInfo?name=disease_h5'
>>> headers = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36'}
>>> resp = requests.get(url, headers=headers)
>>> resp_json = resp.json()
>>> data = json.loads(resp_json['data'])

三、探索数据内容

获取数据后,探索一下数据的结构。

>>> type(data)
<class 'dict'>
>>> data.keys()
dict_keys(['lastUpdateTime', 'chinaTotal', 'chinaAdd', 'isShowAdd', 'chinaDayList', 'chinaDayAddList', 'dailyNewAddHistory', 'dailyDeadRateHistory', 'dailyHealRateHistory', 'areaTree', 'articleList'])

可以发现,数据中包含lastUpdateTime, chinaTotal, chinaAdd, isShowAdd, chinaDayList, chinaDayAddList, dailyNewAddHistory, dailyDeadRateHistory, dailyHealRateHistory, areaTree, articleList这些内容。
下面以chinaTotal为例,可以发现在chinaTotal中有confirm, suspect, dead, heal, nowConfirm, nowSevere这些字段,其他类似,不再重复。

>>> data['chinaTotal']
{'confirm': 68586, 'suspect': 8228, 'dead': 1666, 'heal': 9476, 'nowConfirm': 57444, 'nowSevere': 11272}

根据探索的字段名称,以及将字段值与卫健委数据核对,确认字段所表示的含义,整理如下,其中标红的部分是之前存在,但在最近几次运行时发现已经被移除的内容。

数据梳理结果

四、整理数据

在探索了数据的结构后,对整理的方式便有了大概的框架。比如,表名标为黄底的为即时数据,分别成表;表名标为绿底的为每日数据,拼接在一起成为一个大表;areaTree是世界各国及国内各省市的即时数据,国家、省份、地区各自成表;新闻单独成一表。字段整理方式不再赘述。
整理数据及输出数据的代码请见:https://gitee.com/studentjz/data_analysis_practice/blob/master/nCoV/Python/retrieve_data.py

五、定时取数

为避免每次手动运行取数,写了一个循环,用于定时取数,代码及运行过程如下:

import sys

args = sys.argv
if len(args) != 5:
    str_msg = '''\nPlease append parameters after file name.
Parameters:
  - script: which script to loop, `raw` or `format`, `format` is deprecated.
  - datetime: the datetime which to end the loop, and in format `yyyymmddhhmm`.
  - hold(sec): the seconds to hold after one loop.
  - leave: 0 or 1,
      if 0 then prompt a message box when encounter errors and do nothing after the loop ends,
      if 1 then hibernate your PC after the loop ends.
Run like:\n$ python loop_crawler.py raw 202001012200 3600 1'''
    print(str_msg)
    exit()
else:
    [script, p_datetime] = args[1:3]
    [hold, leave] = [int(x) for x in args[3:]]


import os
from datetime import datetime
import time

if script == 'raw':
    import get_raw_data as udm
elif script == 'format':
    print('`retrieve_data.py` is deprecated!')
    exit()
#    import retrieve_data as udm


t_end = datetime.strptime(p_datetime, '%Y%m%d%H%M')
i = 1

while datetime.now() < t_end:
    print('{sep} Loop {num} {sep}'.format(sep='-'*10, num=i))
    print('Run time: {}\n'.format(datetime.now()))
    try:
        udm.main()
    except:
        str_msg = '{} -- {}\n'.format(datetime.now(), sys.exc_info()[1])
        with open('Exceptions.txt', 'a') as f:
            f.write(str_msg)
        print('-- encounter error --')
        if leave == 0:
            os.system('msg %username% "Error"')
        break
    else:
        print('{sep} Loop {num} is end {sep}'.format(sep='-'*6, num=i))
        print('-'*30 + '\n\n')
        if (t_end - datetime.now()).seconds < hold:
            break
        time.sleep(hold)
        i += 1

if leave == 1:
    os.system('shutdown /h')

运行过程如下图:


运行过程

六、更新

2020-02-16
运行调试期间多次发现web数据的结构发生了变化,这里没有想到比较简洁的办法来动态调整,如果大家有什么好办法还请指导。如果还有其他不足、不正确的地方,也恳请大家的赐教,谢谢。

2020-02-24
运行期间发现web数据经常发现结构性的变动(具体变动内容请见代码中的注释),由于能力、精力有限,格式化的数据更新到2020-02-23为止,此后仅采集原始数据,不做任何整理,采集脚本请见:https://gitee.com/studentjz/data_analysis_practice/blob/master/nCoV/Python/get_raw_data.py

项目地址:https://gitee.com/studentjz/data_analysis_practice/tree/master/nCoV/Python

七、参考资料

https://blog.csdn.net/zengbowengood/article/details/104171607

https://blog.csdn.net/TomCN0803/article/details/104154961

上一篇下一篇

猜你喜欢

热点阅读