APP下载

基于Python的招聘网站信息爬取与数据分析

2019-08-17

网络安全与数据管理 2019年8期
关键词:爬虫薪资引擎

王 芳

(太原科技大学 计算机科学与技术学院,山西 太原 030024)

0 引言

随着网络数据的爆炸式增长,获取有用的数据显得至关重要,网络爬虫技术则可以有效地获取关键数据信息。该技术是一种按照设计者所设定的规则,模拟成为浏览器,自动驱动抓取网页信息的程序或者脚本。网络爬虫的优点在于,它可以将整个网页完整爬取下来,而且具有高度的自定义性。之后,设计者就可以根据自己想要的数据来改善爬虫,使其删掉无用的信息而保存需要的数据。本文对Python爬虫的设计和数据分析的流程进行详细的阐述,然后对数据进行处理和分析,最终根据不同地区、学历要求等条件对某一职业的薪资进行分析,并将分析的数据可视化展现出来[1-2]。

1 相关背景介绍

1.1 爬虫技术

爬网程序搜寻网页的过程也是对请求和响应的处理。以浏览器渲染网页的过程为例,当用户打开网页时,浏览器会向目标网址所在的服务器发起请求。服务器响应请求并以特定格式的网页返回给浏览器。图1显示了通用的爬虫框架。开发爬网程序时,爬虫设计人员通常会根据爬网目标的特征选择网站中的一些有价值的网页地址作为爬网程序的初始目标。抓取程序开始运行后,这些URL将通过DNS服务器进行调度、解析和获取,以得到相应的IP地址[3]。

图1 爬虫框架

1.2 数据分析

目前,数据分析在各个行业和领域得到了广泛的应用。数据分析的典型应用主要体现在以下三个方面[4]:

(1)摸索性的数据分析。在得到数据时,数据可能会不符合要求,通过绘制表格和运用方程式的计算方法来探究其规律性。

(2)模型的选择和分析。在探索性分析的前提下,研究人员可以根据其规律开发出不同的分析模型,然后通过对这些模型进行分析和探讨,选择一个合适的模型。

(3)推测判断分析。其主要用到的知识是数学统计,根据其统计结果可以推导或估计出模型的准确性和可靠性。

2 基于Python的招聘网站信息爬取与数据分析

2.1 Scrapy框架及运行过程

Scrapy工作流程如图2所示,运行过程如下[5]:

(1)爬虫引擎获得初始请求开始抓取。

(2)爬虫引擎开始请求调度程序,并准备对下一次的请求进行抓取。

(3)爬虫调度器返回下一个请求给爬虫引擎。

(4)引擎请求被发送到加载程序,网络数据通过下载中间件下载。

(5)下载完成后,下载结果将返回到爬虫引擎。

(6)引擎通过中间件将加载器响应返回给搜寻器进行处理。

(7)爬虫处理响应到的内容,将其和新的URL返回给引擎。

(8)处置过的items,通过引擎传送给项目管道,然后引擎将处理结果返回给调度器,调度器就可以策划下一个请求的爬取。

(9)重复以上过程(继续步骤(1)),直到爬取完所有的URL请求。

2.2 Robots协议

Robots协议也叫机器人协议,它会产生一个robots.txt文件,这个文件会限制搜索引擎,即限定哪些界面可以爬取。机器人协议是整个互联网中的一种大家都认可的规则制度。它主要是为了防止一些比较私人化的信息遭到泄漏,对隐私起到很好的保护。因为它不是强制性的,所以搜索引擎需要有意识地遵循它。

Robots协议对站点服务器根目录的具体实现方式进行了存储,格式为txt文件,文件名为Robots.txt。该文件中给出了限制爬虫的规则,主要限制了搜索引擎的爬取权限。

3 招聘信息的爬虫具体设计与实现

3.1 总体设计

本文对某招聘网站进行数据爬取,爬取内容为某一职位的有关招聘信息,包括公司名称、薪资、学历要求、经验要求、地址、岗位需求、职位名称。通过对该网站招聘信息的爬取,可以获取到很多有价值的信息,通多对信息的分析能够帮助求职者了解到某一职业的最新情况。

图2 Scrapy框架运行过程

实现爬虫共分为5大部分:分析初始爬取网页URL及其网页信息、实现爬取、数据存储、数据处理以及数据的分析和可视化。

(1)分析初始爬取网页URL及其网页信息。爬虫以网站的网址为起始点,所以需要对起始网址进行格式上的分析和构造。

(2)实现爬取。完成起始网址的分析后就可以对其分析到的初始URL进行爬取,根据返回结果调用不同的回调函数。

(3)数据存储。将获取到的数据存入MySQL中。

(4)数据处理。在数据分析之前,必须对这些脏数据进行清洗和处理。

(5)数据分析及可视化。

3.2 爬虫模块设计

3.2.1 抓取模块设计

本次爬虫设计的目标是获取不同岗位的招聘信息,爬虫是模拟浏览器的行为,所以在爬取工作前需清楚人工操作浏览器的流程,即清楚信息捕捉的流程。首先打开网站输入一个职位信息,例如Python工程师,这时进入招聘Python工程师概览的网页(称之为一级网页),查看网页源码信息发现这里包含的信息不够完整,需要点开单个招聘信息链接,进入详细招聘信息网页(称之为二级网页),根据分析,这里包含了爬取想要的所有信息,至此,本次爬虫的运行基本流程如图3所示。

图3 爬虫流程图

一个爬虫程序在爬取静态网页时,可以直接从中提取数据,但是爬取动态网页时,因为数据可能并不在网页源码中,就需要进行抓包分析。这里爬取的网站通过分析是静态网页,不需要进行抓包等操作,直接提取数据即可。

直接提取数据有很多方法,Python中常用的有以下几种[6-7]:

(1)正则表达式。

(2)通过Python中提供的库BeautifulSoup将HTML解析为对象进行处理。

(3)Scrapy框架支持XPath,通过XPath提取HTML中的信息。

本次实验使用的是XPath,XPath是一种语言,它描述了一种通过使用基于文档逻辑结构或层次结构路径的寻址语法来定位和处理可扩展标记语言(XML)文档中项目的方法。与每个表达式必须理解文档中的典型XML标记及其序列相比,XPath使得编写表达式变得更加容易。

3.2.2 存储模块设计

Python中可采用的存储方式有很多,常用的有JSON文件、CSV文件、MySQL数据库、Redis数据库以及MongoDB数据库等。本次实验没有涉及分布式爬虫,故选用的是MySQL数据库进行数据存储[8]。对数据进行存储前,需要通过Items.py文件对数据进行格式化处理,处理代码如下:

job =scrapy.Field()

#工作名称

company =scrapy.Field()

#公司名称

site =scrapy.Field()

#公司地点

salary =scrapy.Field()

#薪资

experience =scrapy.Field()

#经验要求

education =scrapy.Field()

#学历要求

requirement =scrapy.Field()

#岗位需求

处理完成后将数据存入数据库,首先创建一个数据库表java用来存储招聘信息,如表1所示。

表1 招聘信息表

3.2.3 数据处理模块设计

(1)脏数据处理

本文使用pandas对数据进行处理,具体步骤如下:

①取出数据

将数据从MySQL数据库中取出,首先创建数据库连接:

conn = pymysql.connect(host='127.0.0.1',port=3306,user='root',password='123456',db='bishe',charset='utf8')

创建数据库连接之后,通过pandas读取数据库:

data = pandas.read_sql("select * from java",con = conn)

读取完成后,将数据转换为pandas能够操作的数据结构DataFrame:

df=pandas.DataFrame(data)

②去重

Pandas的drop_duplicates函数就是用来删除重复记录的,通过以下代码即可获取不重复记录行:

df=df.drop_duplicates(‘company’)

③去除无用数据

获取到的数据不完全是有用信息,比如岗位一列,除Java开发工程师外还有其他的职位,需要去除无关数据:

df=df[df.job.str.contains(r'.*?java.*?|.*?开发.*?')]

这样就可以提取包括Java或者开发的岗位。

(2)数据规范化

爬取到的招聘薪资信息格式有很多种,比如:千/月、万/年、元/天,数据不规范,无法进行分析。使用正则表达式来规范薪资。在搜索引擎中使用正则表达式,在文本处理实用程序(如sed和AWK)以及词法分析中搜索并替换文字处理器和文本编辑器的对话框。许多编程语言或通过内置或通过库提供正则表达式功能[9]。

通过正则表达式就可以根据不同的“规则字符串”,过滤出不同的薪资信息,然后通过替换,将薪资统一成相同格式。以下是核心代码:

low_salary=re.findall(re.compile('(d*.?d+)'),salary)[0]

high_salary=re.findall(re.compile('(d?.?d+)'),salary)

if u'万' in salary and u'年' in salary:

#单位统一成千/月的形式

low_salary = float(low_salary) / 12 * 10

high_salary = float(high_salary) / 12 * 10

elif u'万' in salary and u'月' in salary:

low_salary = float(low_salary) * 10

high_salary = float(high_salary) * 10

else:

low_salary = re.findall(re.compile('(d*.?d+)'),salary)[0]

high_salary=""

low_salary = float(low_salary) / 12 * 10

elif u'万' in salary and u'月' in salary:

low_salary = float(low_salary) * 10

elif u'元'in salary and u'天'in salary:

low_salary=float(low_salary)/1000*21

#每月工作日21天

return low_salary,high_salary

4 数据分析及可视化

本文中数据分析用到的是pandas模块,实现数据可视化用到的工具是matplotlib[10]。

本文对爬取后的数据进行可视化展示和分析。

4.1 整体薪资分析

薪资状况也会影响人们在就业方向上的选择,本文对全国范围内Java开发工程师的薪资分布情况进行了分析和可视化展示,如图4所示。

图4 薪资情况

x轴表示薪资,y轴表示薪资范围内公司的数量,由上图可以看出,在全部范围内,Java开发工程师的整体平均薪资水平集中在7 000/月~13 000/月,说明Java开发工程师的就业前景还是很好的。

4.2 地区分析

图5所示是Java开发工程师在各大城市的占比情况。由图5可知,上海、深圳、北京、广州、南京、杭州这六大城市对Java开发工程师的需求占比达到了全部地区的一半以上,说明这几个城市对Java开发工程师的需求量很大,尤其是上海,在这六个城市中遥遥领先。图6所示为这些城市的平均薪资情况。

图5 地区占比

图6 不同城市薪资

4.3 岗位职责分析

公司不同,其发布岗位的职责需求也大不相同,因此需要对应聘者掌握的技术类别进行详细分析。本文通过Python中的Jieba模块来实现分析过程中对词频和关键词的统计[9]。

Jieba模块支持三种分词模式:

(1)精确模式:试图将该句子切分为较为准确的词段,该模式适用于文本分析。

(2)完整模式:从句子中获取所有可能的单词。该模式快速但不准确。

(3)基于精确模式的搜索引擎模式:尝试将长单词分成几个短单词,可以提高召回率。该模式适合搜索引擎。

Jieba带有一个被称为字典的TXT,其中有20 000多个单词,包含词条出现的次数和词性。本文首先对树结构进行单词图扫描,将20 000多个单词放在一个前缀树中,也就是说一个词的前面几个词一样,表示它们有相同的前缀,就可以用前缀树来存储,具有快速查找的优点。

Jieba分词属于概率语言模型分词。概率语言模型分词的任务是:在全切分所得的结果中找出分词方案S,使P(S)最大。

使用Jieba分词可以在岗位职责中分析出各种词出现的频率,使用Python下的wordcloud模块绘制这些词的词云,如图7所示。

图7 岗位职责词云

在进行完分词统计,清理了无意义的词后,提取出前20个中文词汇及其出现次数,如表2所示。

表2 词汇统计

5 结束语

本文基于Python的Scrapy框架,实现了一个爬取招聘网站信息的爬虫。此爬虫以某招聘网站的招聘信息为目标,爬取Java开发工程师的职位信息,然后对爬取到的数据通过Python中的Pandas、Matplotlib等数据处理和作图模块进行处理分析以及可视化展示。因为该招聘网站的反扒机制不是很强,所以单机爬虫就能满足本项目对数据抓取的要求。爬到的数据满足设计要求,并对这个岗位在不同地区的平均薪资以及岗位要求进行了分析,而且可视化展示出了分析得到的结果,为求职者在寻找职位方面提供了便利。

猜你喜欢

爬虫薪资引擎
利用网络爬虫技术验证房地产灰犀牛之说
不简单以“住房薪资”引才——遵循“一步一重天”的人才发展规律
基于Python的网络爬虫和反爬虫技术研究
新海珠,新引擎,新活力!
大数据背景下校园舆情的爬虫应用研究
三生 三大引擎齐发力
蓝谷: “涉蓝”新引擎
大数据环境下基于python的网络爬虫技术
One Engine Left只剩下一个引擎