眾所周知捂龄,大數(shù)據(jù)的浪潮已經(jīng)來臨,爬蟲已經(jīng)成為獲取數(shù)據(jù)最重要的方式之一亭畜,而爬蟲也會隨著我們業(yè)務(wù)的增長變得越來越多,人工監(jiān)控的成本越來越高迎卤,所以我們也會想各種方式來監(jiān)控每個爬蟲拴鸵,一開始我們是直接從數(shù)據(jù)庫入手,也就是監(jiān)控數(shù)據(jù)庫數(shù)據(jù)的增長量來做為爬蟲是否出異常的依據(jù)蜗搔,我們以一周為期限劲藐,如果一周內(nèi),數(shù)據(jù)落庫的量為個位數(shù)樟凄,我們則確定該爬蟲異常聘芜,但是后來發(fā)現(xiàn)這種方法的局限性,及時性差缝龄,錯誤位置不明確汰现,導(dǎo)致修復(fù)爬蟲時間長。
? ? 后來我想從爬蟲框架入手叔壤,我以python的scrapy爬蟲框架為例瞎饲,首先我們的目的是為了及時監(jiān)控爬蟲異常以及明確的異常位置,讓維護(hù)人員能及時的修復(fù)異常爬蟲炼绘;再者盡量少的修改原本我們的每個爬蟲代碼(最好不修改),一開始我想過修改scrapy框架的源碼也就是修改scrapy框架的異常處理代碼嗅战,但是發(fā)現(xiàn)這并不是很好的方法,也想過封裝xpath等函數(shù)饭望,來反映未捕捉到數(shù)據(jù)時仗哨,但是這種方案也不合理。最后我受到j(luò)ava中異常類定義的啟發(fā)铅辞,在不修改原本其他item的情況下厌漂,多定義ExceptionItem這個類來放異常數(shù)據(jù)具體字段要對照每個項(xiàng)目的具體情況,基本字段有爬蟲名斟珊,錯誤信息苇倡,若需要BUG重現(xiàn)那么還需要對應(yīng)異常的html中的body體,再者就是在每個爬蟲except里面進(jìn)行yeild?exceptionItem囤踩,exceptionItem對應(yīng)字段的獲取根據(jù)具體情況處理旨椒,因?yàn)樗械漠惓L幚矶家粯樱锌梢远x一個工具函數(shù)將相關(guān)字段傳入即可堵漱,進(jìn)行了以上處理后综慎,我們會發(fā)現(xiàn),不管這個數(shù)據(jù)是否異常爬蟲都會拋出一個item勤庐,可能是異常item也可能是正常的item示惊,而原本是若發(fā)生異常則不yield item好港,這樣就會導(dǎo)致我們不知道是原本網(wǎng)站沒有更新數(shù)據(jù),還是爬蟲爬取過程中出了異常米罚。完成了以上工作之后钧汹,我們就要去完成最重要的一步,也就是定義了一個異常pipeline录择,也可以說是過濾發(fā)生異常的item拔莱,scrapy官網(wǎng)我們知道,item可以進(jìn)入多個pipeline隘竭,直到用戶拋出raise DropItem("Duplicate item found: %s" % item)時塘秦,該item不進(jìn)入下一個管道,過濾pipeline可以對每一個item進(jìn)行類型判斷若為ExceptionItem則存入mongodb或者通過消息隊(duì)列發(fā)送到處理中心在最終落到關(guān)系型數(shù)據(jù)庫动看,若為其他非ExceptionItem嗤形,我們還可以對其重要字段是否爬蟲到作為判斷依據(jù),例如新聞的title弧圆、conten沒有爬取到則也生成一個ExceptionItem格式的異常item存入mongodb或者拋到異常消息隊(duì)列,如果字段都正常爬蟲則return item 進(jìn)入下一個管道笔咽,進(jìn)行原本應(yīng)該處理的管道中搔预。
#items.py
在末尾加入
#exceptionPipeline.py
#test_error.py
若有更好的監(jiān)控方法,希望可以共同探討
若該方法有不足之處叶组,望大佬們提出
轉(zhuǎn)移至公眾號:打工人zZ