周顯春
(三亞學(xué)院信息與智能工程學(xué)院,三亞 572022)
網(wǎng)絡(luò)爬蟲是指在互聯(lián)網(wǎng)上自動(dòng)爬取網(wǎng)站上內(nèi)容的程序,也稱為Spider或網(wǎng)絡(luò)機(jī)器人[1]。它廣泛應(yīng)用于搜索引擎、網(wǎng)絡(luò)數(shù)據(jù)挖掘等領(lǐng)域,而且企業(yè)或者個(gè)人用戶也利用網(wǎng)絡(luò)爬蟲從網(wǎng)絡(luò)上收集價(jià)值的信息。例如,如果你要開發(fā)一個(gè)基于用戶的飲食推薦APP,那么你需要網(wǎng)絡(luò)爬蟲能夠在美團(tuán)、餓了么、天下美食等網(wǎng)站許多網(wǎng)頁上獲取菜品的信息,如喜歡的人群、評價(jià)的等級、適合的季節(jié)等信息。
由于需要爬取的信息分布于不同網(wǎng)站、不同頁面上,而這些頁面是相互鏈接,可以采用寬度或?qū)挾葍?yōu)先檢索的方法訪問每個(gè)頁面,同時(shí)對每個(gè)頁面的數(shù)據(jù)按照其特有的規(guī)律進(jìn)行爬取。但是,每次都從頭開發(fā)爬蟲程序是非常費(fèi)事、費(fèi)力的工作。為了提高工作效率,應(yīng)該利用已有的優(yōu)秀的爬蟲框架。利用優(yōu)秀的框架不僅可以節(jié)省成本,提高程序的質(zhì)量,更重要的是可以更專注于爬取所需的數(shù)據(jù)。
本文基于Scrapy爬取個(gè)人簡歷的數(shù)據(jù),可以把收集的個(gè)人信息在人物關(guān)系分析、職位推薦等方面應(yīng)用。
Scrapy[2]是基于Twisted框架的開源爬蟲框架,具有簡單、靈活、易于擴(kuò)展、易維護(hù)、跨平臺等特征,支撐Py?thon2.7及3.4+版本。
數(shù)據(jù)爬取模塊主要使用Spider類的parse啟動(dòng)爬取,使用LinkExractor類初始化提取爬取網(wǎng)頁中的鏈接,Selector類xpath、css方法提取網(wǎng)頁的所需數(shù)據(jù),Item類對爬取數(shù)據(jù)進(jìn)行包裝。
(1)數(shù)據(jù)爬取代碼的實(shí)現(xiàn)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) #獲取畢業(yè)院校
xueli=deal_dict.get_xueli(s)
xuewei=deal_dict.get_xuewei(s)
xueli_wei=xueli+"/"+xuewei#獲取學(xué)歷/學(xué)位
timeofparty=deal_dict.get_timeofparty(s)#入黨時(shí)間
timeofjob=deal_dict.get_timeofjob(s)#參加工作時(shí)間
str_split=s.split(",")
basic={"出生年月:":str_split[3],"性別:":str_split[1],"籍貫:":str_split[4],"民族:":str_split[2],"畢業(yè)院校:":school,"學(xué)歷/學(xué)位:":xueli_wei,"入黨時(shí)間:":timeofpar?ty,"參加工作時(shí)間:":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)爬取數(shù)據(jù)封裝的實(shí)現(xiàn)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()
Scrapy可以把爬取的數(shù)據(jù)存儲到各種數(shù)據(jù)庫,如SQLite、MySQL、MongoDB、Redis。本系統(tǒng)采用 SQLite[4],它是輕量級數(shù)據(jù)庫,具有訪問速度快、操作簡單特點(diǎn)。
(1)數(shù)據(jù)庫操作
Connection=.sqlit3.connect(‘jianli.db’)#連接數(shù)據(jù)庫
Connection.close()#關(guān)閉數(shù)據(jù)庫
還需要獲得curser對象,通過它來操縱數(shù)據(jù)庫,最后使用commit保存操作。
(2)settings.py文件
要啟動(dòng) SQLite,需要在 settings.py中添加如下代碼:
SQLLIT_DB_NAME='scrapy.db'
ITEM_PIPELINES={'JianLi.pipelines.SQLitePipeline':300}
在Pycharm IDE中,添加了main.py文件,內(nèi)容包括 from scrapy import cmdline 和 cmdline.execute("scra?py crawl jianli".split())
圖1 程序運(yùn)行圖
如果爬取靜態(tài)網(wǎng)頁,在使用scrapy shell、fetch、view等命令分析的基礎(chǔ)上,一般可以應(yīng)付。但是,遇到動(dòng)態(tài)網(wǎng)頁,封IP反爬蟲等情況下,需要采用特殊的應(yīng)對方法才可以獲得所需要的數(shù)據(jù)。
動(dòng)態(tài)網(wǎng)頁的數(shù)據(jù)存在于JavaScript編碼中,要想獲得所需的數(shù)據(jù),可以先利用Splash執(zhí)行JavaScript代碼渲染頁面,然后在所得頁面上爬取所需數(shù)據(jù)。
實(shí)現(xiàn)的代碼與前面的最大差異有兩點(diǎn),其一使用SplashReques,取 代 scrapy.Request,其 二 需 要 在 set?tings.py 的 DOWNLOADER_MIDDLEWARES、DUPE?FILTER_CLASS、SPIDER_MIDDLEWARES 中添加與splash相關(guān)的值。
由于訪問速度限制、反爬蟲技術(shù)的原因,造成爬取網(wǎng)頁沒有響應(yīng)。如果仍然想要獲取相應(yīng)的數(shù)據(jù),需要使用scrapy中HttpProxyMiddleware類,主要通過創(chuàng)建它的子類,實(shí)現(xiàn) from_crawler、_set_proxy、_init_方法[4]。
基于Scrapy開源框架設(shè)計(jì)一種通過網(wǎng)頁爬取簡歷數(shù)據(jù)的爬蟲。數(shù)據(jù)證明,在Scrapy的基礎(chǔ)上進(jìn)行爬蟲開發(fā)將極大地提高爬取數(shù)據(jù)的效率,還可以擴(kuò)大爬蟲的適應(yīng)性。但是,仍然存在很多需要改進(jìn)的地方,如網(wǎng)頁圖片的爬取、基于此爬蟲的搜索引擎、基于前端的可視化分析等方面。
[1]徐遠(yuǎn)超,劉江華,劉麗珍,等.基于Web的網(wǎng)絡(luò)爬蟲的設(shè)計(jì)與實(shí)現(xiàn)[J].微計(jì)算機(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網(wǎng)絡(luò)爬蟲[M].北京:清華大學(xué)出版社,2017.