APP下载

Scrapy 框架下区域人口数据爬虫的设计与实现

2021-11-28姚新强

软件导刊 2021年11期
关键词:爬虫网址网页

李 通,姚新强

(1.防灾科技学院 应急管理学院,河北 廊坊 065201;2.天津市地震局 震害防御中心,天津 300201)

0 引言

我国地处世界两大地震带——欧亚地震带和环太平洋地震带包围之中,地震灾害频发。据统计,自1900 年以来,在中国爆发的7 级以上地震约占全球的35%,地震已成为我国自然灾害的群灾之首[1-2]。作为地震灾害的主要承灾体的人,因不同区域人口数量不同、不同区域人口分布情况不同,会产生不同的人口伤亡情况。因此,高精度的区域人口数据是制定区域防震减灾政策的一项重要参考内容,能为震后人员伤亡数量的快速评估提供重要的科学依据[3]。城市人口规模研究较多,如娄格等[4]结合“珞珈一号”夜光数据与土地利用数据,采用多元逐步回归模型有效实现了指定区域的常住人口估算及分布模拟;钮心毅等[5]使用多源移动定位大数据估算结果的交叉检验方法对城市常住人口规模进行检测。以上研究虽然可以获得城市的常住人口规模,但却无法将人口数据具体到街道或者社区级别。

目前,通过搜索引擎可以查询到指定街道或社区的人口数据,但缺点是数据较为分散,不利于快速统一的分析。本文重点研究了如何利用Scrapy 框架设计并实现爬虫,对指定区域人口数据进行高效、准确、完整的爬取。

1 技术介绍

1.1 Python 爬虫及Scrapy框架

伴随着互联网技术的飞速发展,大数据时代已经来到。据统计,到2020 年,全世界每人每天将产生140GB 左右的数据[6]。为剔除无用数据,保存有价值的信息,网络爬虫应运而生。网络爬虫是一种按照人们定义的规则,自动抓取网址上的文字、图片、音频等页面内容或者脚本的程序。目前有许多使用爬虫案例,如百度搜索引擎,利用爬虫技术从海量网站爬取不同信息,通过大数据分析及整理用于用户检索;一些抢票软件使用爬虫技术,通过设置爬虫程序不断刷新12306 网站的余票数量来发现剩余车票信息[7-8]。Scrapy 框架是基于Python 语言编写的用来爬取网站结构性数据内容的应用框架,可用于数据挖掘、数据监测、自动化测试等。使用Twisted 异步网络框架来处理网络通讯,加快了爬取数据的速度,不用异步框架及各种中间件接口就可灵活完成各种需求,具有结构简单、便于理解、高效迅速的特点[9-10]。因此,本文选择Scrapy 框架实现地理人口数据的爬取。

Scrapy 框架由5 个部分组成[11]:

(1)Scrapy Engine(Scrapy 引擎)。主要负责其他4 个部分的中间通讯、数据传递等。

(2)Scheduler(调度器)。负责接受引擎发送过来的Request 请求,并按照一定的方式进行整理排列、入队,当引擎需要时交还给引擎。

(3)Downloader(下载器)。负责下载Scrapy Engine 发送的所有Requests 请求,并将其获取到的Responses 交还给Scrapy Engine,由引擎交给Spider 来处理。

(4)Spider(爬虫)。负责处理所有Responses,从中分析提取数据,获取Item 字段需要的数据,并将需要跟进的URL 提交给引擎,再次进入Scheduler。

(5)Item Pipeline(实体管道)。负责处理Spider 中获取到的Item,并进行后期分析、过滤、存储处理等。

Scrapy 架构及数据流向如图1 所示。

1.2 XPath

XPath 即XML 路径语言(XML Path Language),最初是用来搜寻XML 文档用的,但也适用于HTML 文档搜索。XPath 功能十分强大,可用于字符串、数值、时间的匹配以及节点、序列的处理等,并且提供超过100 多个内建函数,涵盖了平时搜寻指定文档的常用方法,使用起来方便快捷。由于要爬取的网站采用HTML 代码编写,所以在爬取结构性数据时选择XPath 方法进行定位和选择[12]。

Fig.1 Scrapy architecture diagrams and data flow图1 Scrapy 架构及数据流向

1.3 正则表达式

正则表达式即Regular Expression,给计算机操作和检验抽取字符串数据提供了一种工具,通过普通字符、元字符和限定符构成一组文字模式对字符串进行匹配、检索、替换等,几乎在所有语言中都能使用[13]。本文通过分析目标网址中要爬取的数据可知,在对北京市最小一级的人口分布区域——社区的爬取过程中,需要使用正则表达式来查找社区的具体人数。

2 爬虫过程设计

2.1 网页结构分析

本文将目标网址(http://www.tcmap.com.cn/beijing/)数据分为三层,分别为北京市区人口数据、区下面不同街道的人口数据、街道下面不同社区的人口数据,呈现出一种典型的树状结构分布。北京市区人口数据在目标网址的第一层页面上呈现出有规律的分布,如图2 圆形框标注区域所示;第二层页面中的各个区下面不同街道的人口数据在列表中呈现出有规律的分布,如图3 圆形框标注区域所示,这两项人口数据均可通过XPath 的方式获得。第三层页面中各个街道下面不同社区的人口数据则是隐藏在社区介绍的字符串中,需要使用正则表达式方法检索其中的人口数据,如图4 圆形框标注区域所示。

经初步分析网页机构可知,部分社区介绍中带有具体的社区人数,部分社区介绍则仅仅提供了户数,对于仅提供户数的社区,爬虫程序需要将提取的户数乘以3.5 作为该社区的人数。同时,目标网址需要进行多级页面跳转,涉及多层URL 数据,因此需要对跳转的URL 进行保存[14]。

2.2 网页爬取流程

网络爬虫在爬取网页时遵循爬取策略规则[15]:

(1)宽度优先搜索策略。在HTML 文档中,将获取的给定起始链接所有子节点放入待抓取URL 队尾,对子链接继续获取其所有子节点,以达到最大宽度的搜索效果。

(2)深度优先搜索策略。在HTML 文档中,以搜寻到叶节点为目标,即顺着给定的起始链接一直搜寻到不能再继续向下搜寻为止,然后再返回到上一层节点继续向下搜寻。

Fig.2 Population data of Beijing urban district图2 北京市区人口数据

Fig.3 Demographic data of Donghuamen Subdistrict,Dongcheng District,Beijing图3 北京市东城区东华门街道人口数据

Fig.4 Demographic data of Duofu Lane Community,Donghuamen Street,Dongcheng District,Beijing图4 北京市东城区东华门街道多福巷社区人口数据

(3)IP 地址搜索策略。给定爬虫程序一个起始的IP 地址,以递增的方式搜寻IP 地址段后每一个地址中的文档,完全不考虑文档中指向其他Web 站点的文档链接。

(4)大站优先搜索策略。爬虫程序通过分析待抓取列表中URL 的域名类别进行分类统计,按照数量的大小顺序进行抓取。

本文通过分析目标网址上人口数据呈树状结构分布的情况,选择深度优先策略,具体的网页爬取流程分为以下步骤[16-17]:①在Spiders 中通过继承scrapy.Spider中的start_requests 函数,由初始URL 地址生成Request 请求发送到Scrapy Engine;②Engine 将Request 不作任何处理发送到Scheduler 中并按照一定方式排列入队;③Scheduler 将生成的Request 请求交还给Scrapy Engine,并由Scrapy Engine 交由Downloader 进行下载并返回给Scrapy Engine 对应的Re⁃sponse数据;④Scrapy Engine 将Response 数据交由Spider,根据设定的解析方法爬取人口数据Item,同时将要跳转的URL 网址以Request 方式生成;⑤将Item 及Request交由Scrapy Engine,分别发送至Item Pipeline 和Scheduler 进行持久性存储和入队处理;⑥当Scheduler 中不存在任何Re⁃quest 后爬虫程序停止运行。

爬取流程如图5 所示。

Fig.5 Flowchart of web crawling图5 网页爬取流程

2.3 反爬虫机制应对措施

网络爬虫在爬取过程中会在短时间内向目标网址发出大量的网络请求,占用网络带宽,使其他用户访问该网站时变得卡顿,甚至可能造成服务器崩溃。因此,许多网址都采取了反爬虫机制,例如分析用户请求的IP 地址在短时间内访问的频率、识别请求中所携带的User-Agent 信息及网站流量统计和日志分析等,以此判别是爬虫访问还是人为访问[18-19]。为防止爬取数据时被反爬虫限制,可以采取以下几个方法:

(1)修改User-Agent 字段,将其伪装成正规的浏览器发出的请求,防止服务器分辨出爬虫程序。

(2)设置代理IP。若大量且快速访问同一个域名下的网页,会被网站识别为爬虫程序,因此需要通过设置代理IP 或者代理服务器的方式来解除网站对于访问频率较高的主机限制。

(3)降低抓取速度。一个IP 地址在1s 的时间内访问许多次,很容易被网站识别为爬虫程序,可通过import time 引入时间模块,设置间隔时间为2s,即在代码中设置time.sleep(2)或在settings.py 文件中设置DOWNLOAD_DELAY=2 来降低爬取速度。

(4)禁用Cookies。有的网站为了识别用户身份或进行session 跟踪,在用户终端上保存了Cookies 信息,因此可以在settings.py 文件中设置COOKIES_ENABLES=False。

3 爬虫过程实现

3.1 Item 数据定义

在Scrapy 框架中,Item Pipeline 负责爬虫数据的分析、过滤、存储处理,由于本文爬取的数据是树形结构,因此分别设置DistrictItems、StreetItems、CommunityItems 三个Item文件来保存区人口数据、街道人口数据、社区人口数据。

3.2 网页爬取

对北京市区和街道的人口数据爬取时,根据网页结构分析可以发现两个网址上人口数据呈现有规律的分布,通过XPath 中following-sibling::*方法依次获取北京市16 个区人口数据和每个区分布的所有街道的tr 标签,提取其中的区或街道名称以及对应的人口数据分别存入相应的Item中,并通过yield 迭代器分别回调streetparse 函数和commu⁃nityparse 函数[20]。部分代码如下:

在爬取社区人口数据时,由于目标网址没有在网页的表格中给出人口数据,而是将其放在社区简介的文字中,因此需要通过正则表达式来筛选匹配相应的人口数据。通过搜寻字符串中第一个以“人”为结尾的数据,若不存在,则搜寻第一个以“户”为结尾的数据,并将得到的数据乘3.5 作为社区人口数据。部分代码如下:

3.3 数据存储

3.3.1 爬虫程序测试

在Terminal 上通过scrapy crawl MySpider 指令可以运行当前代码查看是否存在错误。由于Scrapy 框架采用的是Twisted 异步编程模型,所以运行结果与目标网址上的顺序不一致[21]。部分运行结果如图6 所示。

3.3.2 MySQL 数据库存储

在成功获取想要爬取的人口数据后,需要对得到的数据进行持久化存储。由于JSON 数据可读性较差,因此本文没有选择将数据写入到JSON 文件中,而是选择存入MySQL 数据库[22]。首先根据在Item 中定义的数据模型在数据库中建立scrapydemodata 表,并在pipeline.py 文件中引入Python 第三方模块pymysql,通过调用pymysql 的connect方法传入数据库主机名、用户名、登陆密码等信息获得数据库连接对象。在成功连接数据库后定义process_item 方法,使用SQL 语句将爬取到的人口数据存入数据库中,数据库存储的人口数据信息如图7 所示。

Fig.6 Operation results of the crawler图6 爬虫程序运行结果

Fig.7 Part of the population data in the database图7 数据库中部分人口数据信息

4 结语

本文设计了基于Scrapy 框架的区域人口数据爬虫程序,实现对指定网址的人口数据爬取,以获得市区、街道和社区三级人口数据,并通过数据库将所得数据存入MySQL数据库中,方便地震研究人员对数据进行查询、统计和分析,以便估算出特定区域的人口伤亡数,为震后人员伤亡评估提供重要的科学依据。随着爬虫与反爬虫技术的不断升级,程序还有许多需要优化的环节,如网页页面结构更新,在数据筛选过程中解析模块就需要重新写入,在开发时可以扩展做成通用性爬虫;在某些添加了滑块验证码反爬虫机制的网站上还需要对破解验证码进行深入研究。

猜你喜欢

爬虫网址网页
2023年6月全宅影音器材编辑推荐
利用网络爬虫技术验证房地产灰犀牛之说
本刊网址变更通知
基于Python的网络爬虫和反爬虫技术研究
基于CSS的网页导航栏的设计
利用爬虫技术的Geo-Gnutel la VANET流量采集
基于URL和网页类型的网页信息采集研究
大数据环境下基于python的网络爬虫技术
网页制作在英语教学中的应用
本刊网址变更通知