基于个人简历的Scrapy设计与实现
2018-07-06周显春
周显春
(三亚学院信息与智能工程学院,三亚 572022)
0 引言
网络爬虫是指在互联网上自动爬取网站上内容的程序,也称为Spider或网络机器人[1]。它广泛应用于搜索引擎、网络数据挖掘等领域,而且企业或者个人用户也利用网络爬虫从网络上收集价值的信息。例如,如果你要开发一个基于用户的饮食推荐APP,那么你需要网络爬虫能够在美团、饿了么、天下美食等网站许多网页上获取菜品的信息,如喜欢的人群、评价的等级、适合的季节等信息。
由于需要爬取的信息分布于不同网站、不同页面上,而这些页面是相互链接,可以采用宽度或宽度优先检索的方法访问每个页面,同时对每个页面的数据按照其特有的规律进行爬取。但是,每次都从头开发爬虫程序是非常费事、费力的工作。为了提高工作效率,应该利用已有的优秀的爬虫框架。利用优秀的框架不仅可以节省成本,提高程序的质量,更重要的是可以更专注于爬取所需的数据。
本文基于Scrapy爬取个人简历的数据,可以把收集的个人信息在人物关系分析、职位推荐等方面应用。
1 Scrapy架构概述
Scrapy[2]是基于Twisted框架的开源爬虫框架,具有简单、灵活、易于扩展、易维护、跨平台等特征,支撑Py⁃thon2.7及3.4+版本。
2 系统设计及代码
2.1 个人简历数据抓取模块
数据爬取模块主要使用Spider类的parse启动爬取,使用LinkExractor类初始化提取爬取网页中的链接,Selector类xpath、css方法提取网页的所需数据,Item类对爬取数据进行包装。
(1)数据爬取代码的实现def parse(self,response):
url_complex=LinkExtractor(restrict_xpaths='//div[con⁃tains(@class,"nav")]/ul/li')
for link in url_complex.extract_links(response):
if link.url:
yield scrapy.Request(link.url,callback=self.complex_parse)
def GB_special_parse(self,response):
url=response.xpath('//div[contains(@class,"peo⁃ple_show")]/a/@href')
#url_first=url= response.xpath('//div[contains(@class,"people_show")]/a/@href')
if len(url)>0:
url=url[0].extract()
else:
url=response.xpath('//dd[contains(@class,"brown")]/a/@href')[0].extract()
yield scrapy.Request(url,callback=self.complex_parse)
def complex_parse(self,response):
def add_basic_situation(s):
deal_dict=basic_function() #获取基本信息
school=deal_dict.get_school_infor(s) #获取毕业院校
xueli=deal_dict.get_xueli(s)
xuewei=deal_dict.get_xuewei(s)
xueli_wei=xueli+"/"+xuewei#获取学历/学位
timeofparty=deal_dict.get_timeofparty(s)#入党时间
timeofjob=deal_dict.get_timeofjob(s)#参加工作时间
str_split=s.split(",")
basic={"出生年月:":str_split[3],"性别:":str_split[1],"籍贯:":str_split[4],"民族:":str_split[2],"毕业院校:":school,"学历/学位:":xueli_wei,"入党时间:":timeofpar⁃ty,"参加工作时间:":timeofjob}if basic==None:return{}
else:return basic
Senior=SeniorCadreItem()
content= response.xpath('//div[contains(@class,"people_text")]'
Senior['name']=content.xpath('.//h2/text()').extract()[0].replace("同 志 简 历 ","") experince_ex=[re.sub(' |u3000| ',"",ex)for ex in content.xpath('.//p/text()').ex⁃tract()]
experince_list=[i for i in experince_ex if len(i)>0]
experince=" ".join(experince_list)
Senior['experince']=experince
Senior['post']=experince_list[1]
str=experince_list[0]
str=add_basic_situation(str)
basicfunction=basic_function()
Senior=basicfunction.deal_dict_situation(str,Senior)
yield Senior
(2)爬取数据封装的实现class JianLiItem(scrapy.Item):
name=scrapy.Field()
post=scrapy.Field()
birth=scrapy.Field()
sex=scrapy.Field()
timeofwork=scrapy.Field()
placeofbirth=scrapy.Field()
nation=scrapy.Field()
school=scrapy.Field()
degree=scrapy.Field()
timeofparty=scrapy.Field()experince=scrapy.Field()
2.2 数据存储模块
Scrapy可以把爬取的数据存储到各种数据库,如SQLite、MySQL、MongoDB、Redis。本系统采用 SQLite[4],它是轻量级数据库,具有访问速度快、操作简单特点。
(1)数据库操作
Connection=.sqlit3.connect(‘jianli.db’)#连接数据库
Connection.close()#关闭数据库
还需要获得curser对象,通过它来操纵数据库,最后使用commit保存操作。
(2)settings.py文件
要启动 SQLite,需要在 settings.py中添加如下代码:
SQLLIT_DB_NAME='scrapy.db'
ITEM_PIPELINES={'JianLi.pipelines.SQLitePipeline':300}
2.3 程序运行效果
在Pycharm IDE中,添加了main.py文件,内容包括 from scrapy import cmdline 和 cmdline.execute("scra⁃py crawl jianli".split())
图1 程序运行图
3 存在问题及解决方法
如果爬取静态网页,在使用scrapy shell、fetch、view等命令分析的基础上,一般可以应付。但是,遇到动态网页,封IP反爬虫等情况下,需要采用特殊的应对方法才可以获得所需要的数据。
3.1 动态数据的爬取
动态网页的数据存在于JavaScript编码中,要想获得所需的数据,可以先利用Splash执行JavaScript代码渲染页面,然后在所得页面上爬取所需数据。
实现的代码与前面的最大差异有两点,其一使用SplashReques,取 代 scrapy.Request,其 二 需 要 在 set⁃tings.py 的 DOWNLOADER_MIDDLEWARES、DUPE⁃FILTER_CLASS、SPIDER_MIDDLEWARES 中添加与splash相关的值。
3.2 使用HTTP 代理
由于访问速度限制、反爬虫技术的原因,造成爬取网页没有响应。如果仍然想要获取相应的数据,需要使用scrapy中HttpProxyMiddleware类,主要通过创建它的子类,实现 from_crawler、_set_proxy、_init_方法[4]。
4 结语
基于Scrapy开源框架设计一种通过网页爬取简历数据的爬虫。数据证明,在Scrapy的基础上进行爬虫开发将极大地提高爬取数据的效率,还可以扩大爬虫的适应性。但是,仍然存在很多需要改进的地方,如网页图片的爬取、基于此爬虫的搜索引擎、基于前端的可视化分析等方面。
[1]徐远超,刘江华,刘丽珍,等.基于Web的网络爬虫的设计与实现[J].微计算机信息,2007,23(21):119-121.
[2]https://doc.scrapy.org/en/latest/intro/tutorial.html.
[3]http://www.sqlite.org/index.html.
[4]刘硕.精通Scrapy网络爬虫[M].北京:清华大学出版社,2017.