使用网络爬虫技术获取新冠病毒疫情数据的应用研究
2020-07-27林丽星
林丽星
(闽西职业技术学院 信息与制造学院,福建 龙岩 364021)
2019-2020年爆发的新型冠状病毒肺炎,2020年1月12日被世界卫生组织命名为COVID-19[1]。在此之前人类身上并未发现过新型冠状病毒。患者感染了新型冠状病毒后,在潜伏期便很容易传染给别人,而自身一旦发病会导致呼吸困难,少数病情危急会导致死亡。
新型冠状病毒的传播方式,更多是通过呼吸道空气飞沫传播和亲密接触的形式达到人传人的恶劣局面。至于是否存在气溶胶方式传播,在试行第六版诊疗方案指明只有在相对封闭的环境中,同时气溶胶浓度处于高浓度状态下,才存在传播的可能性[2]。
目前全世界疫情形势并不乐观,新冠状病毒的肆虐,所有中国人以及整个世界都在关注着疫情的消息,关注着数据的变化,盼望着拐点的出现,患病人数的减少,治愈病例的增多。各大主流网站每天都在播报各类数据,包括新增的,治愈的病例等,单纯的数字显示不够直观,如果能够获得疫情相关的数据,并对其进行分析,并采用可视化的图表形式来显示疫情数据的变化。可视化图表的显示更为直观清晰。在获取相关的疫情数据时我们借助网络爬虫来爬取疫情数据,使用python提供的充足的类库功能对其进行分析并转换为直观的折线图来显示。
1 疫情数据获取可采用的技术
要爬取网络上的数据,可使用网络爬虫来实现。网络爬虫(spiderr或web crawle),也有人称之为网络蜘蛛,像蜘蛛一样在网络上爬行并获取所需要的数据。网络爬虫是一段程序,它从网页上获取信息,然后对这些信息进行处理,转换成用户所想要的数据,并把结果反馈给用户。web crawler构成了搜索引擎重要的组成部件,但现在网上常用的搜索引擎大多是按照关键字进行检索,检索出来的数据是尽可能大地覆盖全网络,因为检索数据也是多样化,有文字、图片、音视频等。对于一些网上非结构化数据,并且信息含量比较多的数据,目前的搜索引擎可能不能很好地去搜寻出用户想要的数据。而网络爬虫就能很好地解决一般搜索引擎的局限性。
在数据爬取时,可以使用Python来进行爬取。Python语言的语法简单明了,开发环境清晰,学习难度较低。Python语言是解释性的脚本语言,它是开源的,而且具有平台无关性,可以高效地开发各种应用程序。Python拥有大量的扩展库,这些扩展库相对成熟,而且能够支持几乎所有的领域应用开发。因此,对于科研人员进行处理工程技术问题,实验数据的处理、图表的制作以及进行科学计算分析,Python都非常适用。
要获取疫情数据,使用到 Python的库有Numpy库,用于处理数组和矢量运算;Pathon库用于处理数据结构及进行数据分析;Matplotlib库用于将数据分析结果以图表的形式显示出来。
2 网络爬虫技术获取疫情数据的步骤
抓取网页中的数据,采用的步骤是:抓取数据,对数据进行筛选清洗,清洗好的数据为了更持久的使用存储于本地机中,对数据进行分析处理,最后以可视化的形式显示出来。
2.1 搜索数据
在网络上搜寻数据的时候,因为 AJAX技术的存在,必须使用基于事件驱动的爬虫引擎。根据新冠疫情数据这一主题,对页面内容或是对应的URL链接进行搜索,对页面的主题进行判断,根据主题去搜索相关的网页。根据主题进行数据的爬取,最重要的是确定高效的主题判定策略。常用的主题判定策略有基于网页内容的判定策略、基于网页链接的判定策略及混合内容及链接的判定策略。
从fish-search算法到best first serach算法,算法并不是对所有的URL进行爬取,只是选择预测相似度较高的网址进行爬取。不管是爬行主题随爬行过程动态变化的主题爬虫还是基于文本位置的爬虫还是根据关键字 key分类进行相关度判定的爬虫,都只是把网页内的文本内容做为主题进行判定,没有考虑到链接,所以在数据获取的时候,会导致某些数据的遗漏。
PageRank算法及 HITS算法,只考虑网页的链接结构,虽然能够发现关键网页,具有全局观,能指导爬虫爬取的方向,但是因为没有考虑到页面的内容,所以有可能会出现主题不匹配的现象,爬取的数据跟用户所需要的数据会差别较大。
所以在爬取数据时,一般会结合网页内容和网页链接一起进行判定。比如说可以先对网页的链接进行分析,不同指向的URL进行不同的定义,外向链表示站外网址,交叉链表示友情链接,水平链表示同级网址,下行链表示下级网址,上行链表示上级网址。根据不同的链接判定主题内容的相关性。内容与链接的结合,覆盖率及准确率都有所提高。所以我们在爬取数据的时候,更多的是两者结合一起使用。
2.2 抓取数据
数据爬取的时候,根据HTML标签去爬取标签中存储的文本数据。除此之外,还会去爬取标签的属性中存储的数据。根据网络中数据类型的不同,爬虫爬取数据的方式也有区别。如果是结构化数据格式,无须处理直接转换即可,比如json格式的数据,比如 xml数据;对于非结构化数据,比如HTML格式的数据,不能直接使用,必须先进行处理,可使用正则表达式,xpath,bs4等。
Json数据是一种轻量级的数据交换格式,阅读与编写容易,也方便机器的解析与生成,非常适合进行数据交互的场景。在爬取新冠数据的时候,使用 json.loads(requests.get(url=findurlv)json()['data'])从腾讯网站中通过网址来抓取数据。数据抓取时,通过jsonpath来解析json数据,有N重嵌套的 json数据亦能分析并获取想要的信息。jsonpath能够用于从 json文档中获取用户想要的数据。
非结构化数据使用 bs4进行分析,在分析的时候,先定义一个 beautifulsoup对象。在这个beautifulsoup对象中将要爬取的页面源码数据加载进去,然后使用此对象的属性和方法来实现标签的定位和进行数据的提取。
xpath是目前解析效率较高且通用性最强的解析方式。在解析的时候通过实例化一个etree对象,并且将目标页面的源码数据加载到此对象中,然后通过使用etree对象的xpath方法结合对应的表达式进行标签的定位和数据的提取。Python的Numpy库提供了标准的数学函数能够对数据进行快速的运算,而且还提供了很多基于C语言的API,使用很方便,同时还能提高数据的运算效率。[3]
在获取新冠疫情数据时,通过内容与链接分析,最终爬取腾讯网站上的关于疫情变化的相关数据。从网站上爬取的数据是结构化数据,所以在 python中直接保存为 json格式的数据即可。alldata=json.loads(requests.get(url=findurlv)json()['data'])#抓取数据
2.3 数据筛选
获取网页上的数据后,并不是马上就能使用,往往要进行筛选,清洗才能提取实际需要的数据。对于一些无用数据,或是相同数据进行删除,对一些有误数据进行检验。对于缺少或是丢失的值,可以使用lambda函数来查看,并且在确定缺失原因后,可以考虑用指定数来补充。对于连续变量的处理较为简单,可以设定为平均值或者设定为中位值。分类变量可以考虑用众数来补充。对于一些异常值,单变量用盖帽法或是分箱法来处理,多变量用聚类法来处理。数据的清洗可以使用Pandas库,它提供了方便的类表格的统计操作和类SQL操作,同时还提供了强大的缺失值处理功能,使用数据预处理工作更加方便快捷。[4]在获取疫情数据时,只需要时间及各类患者人数的数据,所以只需对其按时间排序即可。
alldata.sort(key=lambda x:x['date'])#按日期排序
2.4 数据存储
爬取到网页数据后,将数据存储起来进行下一步的处理。常见的数据存储方式有三种,可以将数据存储成文本txt文件或是csv文件;或是以数组的形式存储或是存储到数据库中。在爬取新冠疫情数据的时候,将数据存储于数组中,按日期排序,依次获取确诊,疑似,死亡及治愈数量。对应代码为:
#获取各类人数放至数组中
confirmsick_list.append(int(item['confir m']))
suspectsick_list.append(int(item['suspect']))
deadsick_list.append(int(item['dead']))
healsick_list.append(int(item['heal']))
2.5 分析并可视化呈现
图1 疫情走势图
对数据进行分析,根据分析结果使用 python的 MatPlotlib库把数据分析结果以折线图的形式显示出来。使用MatPlotlib库,用户只需要书写少量的代码就能够绘制多种高质量的二维或三维图形。pyplot是MatPlotlib库的关键模块,提供了很多接口,能够快速地构建多种图表,比如函数图像、直方图及散点图等。[5]使用时,调用相对应的接口即可。因为要反映疫情的变化情况,所以使用折线图来显示。关键代码为:
plt.figure('疫情走势图', facecolor='#e3e3e3', figsize=(11, 6))
plt.title('疫情走势图 ', fontsize=35)
plt.plot(li_alldate,confirmsick_list,label='确诊人数')
plt.plot(li_alldate,suspectsick_list,label='疑似人数')
plt.plot(li_alldate,healsick_list,label='治愈人数')
plt.plot(li_alldate,deadsick_list,label='死亡人数')
plt.gca().xaxis.set_major_formatter(mdates.Dat eFormatter('%m-%d'))
plt.gcf().autofmt_xdate()
today=time.strftime("%Y-%m-%d %H:%M:%S",time.localtime())
plt.xticks(pd.date_range('2020-01-13',today),rotation=90)
plt.grid(linestyle=':')
plt.legend(loc='best')
plt.savefig('疫情走势图.png')
#plt.show()
绘图函数处理后的结果以图片的形式保存,因为腾讯网站上的疫情数据是从1月13号开始的,所以截止到3月5号的数据对应折线图如图1所示。图1的折线图可以很直观地显示新型冠状病毒疫情的趋势走向。
3 结语
借助python语言及其强大的扩展库进行疫情数据的爬取,通过其丰富的库及强大的快速绘图功能,能非直观地用折线图显示疫情的趋势走向。