一种数据采集与分析平台的研究与设计
2021-02-26杨宇
杨宇
(贵州电子信息职业技术学院,贵州 凯里 556000)
1 引言
随着互联网大数据技术的不断发展[1],数据成为最宝贵的资源,网络数据采集技术成为热门的研究领域之一。Python 具有易于配置、处理字符灵活等特性,且具有Urlib、Requests、Selenium 等丰富的网络爬虫模块[2],但这些模块在进行网络数据爬虫时,性能差、耗时长、效率低、易阻塞。Scrapy框架是基于Python语言编写的网络爬虫框架[3],具有效率高、非阻塞、异步爬取等特性,能够有效解决Python内置网络爬虫模块的不足。公交是市民日常出现最为重要的交通数据,对公交数据进行采集分析具有重要的意义。本文采用Scrapy 爬虫技术,结合Kelltle 数据预处理技术[4]、Flask+Echarts数据可视化技术[5],搭建一种数据采集与分析平台。
2 系统整体设计
该系统整个平台设计如图1所示。
图1 平台设计框图
该平台主要由数据采集、数据预处理、数据存储及数据可视化四个子模块构成。数据采集通过Scrapy框架实现,采集到的数据存储到CSV文件中;数据预处理由Kelttle工具实现,网络爬虫模块爬取到的数据需要经过数据预处理模块进行预处理;数据预处理完成以后,将结果保存到MySQL数据库中;最后,通过Flask+Echarts框架搭建数据可视化模块,实现分析结果的可视化。
3 系统详细设计
3.1 数据采集
Scrapy是Python开发的一个快速屏幕抓取和Web抓取框架,用于抓取Web 站点并从此页面中提取结构化数据,它是Python爬虫技术中最为常用的一个框架[6],其构架如图2所示。
图2 scrapy构架图
有关Scrapy的各个部分的组件的详细说明如下:
(1)引擎(Scrapy Engine):负责其他部件的通信信号和数据传递。
(2)调度器(Scheduler):将Request请求排列入队。
(3)下载器(Downloader):用于高速下载网络资源。
(4)蜘蛛(Spiders):解析Response 数据,获取Item 中定义的字段数据。
(5)项目管道(Item Pipeline):用于处理Spider中获取的数据。
(6)下载中间件:主要用来处理Scrapy引擎与下载器之间的请求及响应。
启动数据采集后,引擎会打开一个网站,找到处理该网站所用的Spider,并向该Spider 请求第一个爬取的URL。引擎从Spider中获取到第一个爬取URL,并通过调度器以Request形式进行任务调度,随后引擎会向调度器请求下一个需要爬取的URL,调度器将下一个要爬取的URL给引擎,引擎通过下载中间件将URL 发送给下载器,下载器开始启动页面下载,下载完成后即可生成Response 对象,然后通过下载中间件返回给引擎,引擎收到Response对象后,通过爬虫中间件将其发送给Spider进行处理。Spider从Response对象中提取Item数据对象及新的Request请求,一同发送给引擎,引擎将Item 数据对象给项目管道,对数据进行持久化操作,将新的Request请求交给调度器,进行新一轮的下载调度。通过多组件相互协作,不同组件负责不同工种,实现组件之间异步处理,从而有效利用网络带宽,提高数据爬取及处理的效率。
设计流程:
新建Scrapy项目工程,在工程目录结构中,setting.py负责爬虫相关配置,其中爬虫名称配置如下:
BOT_NAME='beijingbus'
请求头配置如下:
管道配置如下:
数据库配置如下:
DB_HOST='localhost'
DB_USER='root'
DB_PWD='12101210'
DB='beijingbus'
DB_CHARSET='utf8'
管道配置如下:
其中,数字代表优先级,数字越小,优先级越高。
items.py负责定义需要爬取的字段域等信,如下:
bus_name=scrapy.Field()#公交线路名
bus_type=scrapy.Field()#工具类型
bus_time=scrapy.Field()#运行票价
bus_ticket=scrapy.Field()#公交票价
bus_company=scrapy.Field()#公司名
wang_info=scrapy.Field()#往车站信息
fan_info=scrapy.Field()#返车站信息
Spider包下的bei_bus.py负责数据爬取与响应数据xpath解析,主要在BeiBusSpider类中实现,在该类中,函数start_requests 主要实现以数字1-9,以字母:BCDFGHKLMPSTXYZ开头的url的拼接及请求发送,核心代码如下:
url'{url}/list{page}'.format(url=self.start_urls,page=(page+1))#URL拼接
yield Request(url,callback=self.parse_index1)#请求发送
函数parse_index1 负责提取详细被包含公交线路url,并于start_url 进行拼接,得到完整的详细公交线路url,核心代码如下:
beijingbus = response.xpath('//div[@class="list clearfix"]//a/@href').extract()#通过xpath 提取每一班公交子url,再将其和start_url拼接,然后将完整的url请求发送到下一级处理函数parse_detail2,该函数主要通过xpath 实现详情页数据提取。任意举例3个属性,核心代码如下:
bus_name = response.xpath('//div[@class="info"]/h1//text()').
extract_first() #公交名称
bus_time = response.xpath('//div[@class="info"]/ul/li[1]//text()').extract_first() #运行时间
bus_type=response.xpath('//div[@class="info"]/ul/li[2]//text()').extract_first() #线路路线
Spider 包下的run.py 负责整个爬虫工程运行,实现代码如下:
from scrapy import cmdline
cmdline.execute('scrapy craw l bei_bus'.split()),其 中,bei_bus为爬虫名。
pipelines.py 负责接收spider 爬取的数据,并将数据进行持久化等操作,主要是将爬取到的数据写入csv文件中,主要实现代码如下:
其中函数__init__负责初始化工作,主要是打开需要写入数据的csv文件及定义写入规则,函数process_item主要实现数据的封装与写入csv文件。
综上,整个公交数据爬取详细流程如图3所示。
图3 数据爬取流程图
3.2 数据清洗
数据预处理采用Kettle工具实现,Kettle是一款比较实用的ETL 工具,通过图形化描述数据清洗的整个流程,其在数据清洗时,主要由转换负责完成,它是ETL 解决方案中重要的组成部分之一,其主要用于数据的抽取、转换以及加载等操作,本质是一组图形化的数据转换配置的逻辑结构。一个转换包括一个或多个步骤,例如读取文件、过滤输出行、数据清洗或将数据加载到数据库等步骤。转换中的步骤是通过跳来连接的,跳定义了一个单向通道,允许数据从一个步骤向另一个步骤流动。在Kettle中,数据的单位是行,数据流就是数据行从一个步骤到另一个步骤的移动[7]。数据清洗的主要流程如图4所示。
图4 数据清洗流程
在进行数据清洗前,需要先通过Kettle 工具创建一个转换,导入需要处理的数据,重点对重复值及缺失值进行处理,最终将处理后的结果导出到MySQL数据库中进行存储。
3.3 数据存储
数据存储采用MySQL 数据库实现,爬虫过程中的数据持久化即是将数据写入MySQL 数据库,数据库表单结构如表1所示。
表1 数据库表单结构
3.4 数据可视化
数据可视化采用Flask+Echarts技术框架进行设计,Flask是Python Web 开发的微框架,在Flask 框架的基础上再采用SQLAlchemy 技术编写数据库映射模型,完成数据库表结构映射模型。Echarts 通过Javascript 发挥强大作用,实现数据的动态可视化。数据可视化设计流程如图5所示。
图5 数据可视化设计流程
4 结果分析
整个实验的环境说明如表2所示。
表2 实验环境说明
4.1 数据预处理
数据预处理试验结果如图6及表3所示。
从图6及表3得出输入的公交车数据为1089条,过滤、去重后得到的公交车数据为689条,清洗掉不满足条件数据为400条。
图6 数据预处理转换图
表3 数据预处理过程
4.2 数据可视化
公交线路类型可视化如图7所示。
从图7分析得知:北京公交线路类型分为市区普线、郊区普线及通勤普线三类,市区普线占比高达70.97%。
图7 公交线路类型占比
公交的可视化如图8所示。
图8 公交往返线路
从图8得知:北京往返线路多,交叉站点多,从而给乘客提供较多的乘坐方案。
5 结语
本文通过Scrapy 数据采集、Kettle 数据清洗、MySQL 数据存储及Flask 整合Echarts 数据可视化,提供一种数据采集与分析平台的详细设计思路,并以北京公交为例进行数据测试。测试结果表明:系统稳定可靠、操作简单、实时性强,具有一定的社会意义及参考价值。