摘要:實(shí)際運(yùn)行中就發(fā)現(xiàn)了一個(gè)有趣的現(xiàn)象。爬蟲(chóng)抓取的速度超過(guò)了我用給它推送的速度,導(dǎo)致爬蟲(chóng)從獲取不到同時(shí)此刻線程池所有線程都已停止。如何管理設(shè)置,避免返回,且沒(méi)有工作線程時(shí)退出循環(huán)。退出檢測(cè)循環(huán)說(shuō)明結(jié)束了,手動(dòng)調(diào)用來(lái)是退出調(diào)度循環(huán),終止爬蟲(chóng)。
Webmagic源碼分析系列文章,請(qǐng)看這里
從解決問(wèn)題開(kāi)始吧。
問(wèn)題描述:由于數(shù)據(jù)庫(kù)的數(shù)據(jù)量特別大,而且公司沒(méi)有搞主從讀寫(xiě)分離,導(dǎo)致從數(shù)據(jù)庫(kù)讀取數(shù)據(jù)比較慢,而我需要從數(shù)據(jù)庫(kù)查詢出特定標(biāo)識(shí)來(lái)拼url去抓。實(shí)際運(yùn)行中就發(fā)現(xiàn)了一個(gè)有趣的現(xiàn)象。爬蟲(chóng)抓取的速度超過(guò)了我用scheduler給它推送url的速度,導(dǎo)致爬蟲(chóng)從scheduler獲取不到url,同時(shí)此刻線程池所有線程都已停止。這個(gè)時(shí)候,根據(jù)Spider的機(jī)制是要退出調(diào)度循環(huán)的,從而終止Spider。從下面代碼可以看出:(取自Spider的run方法):
while ((!(Thread.currentThread().isInterrupted())) && (this.stat.get() == 1)) { Request request = this.scheduler.poll(this); if (request == null) { if ((this.threadPool.getThreadAlive() == 0) && (this.exitWhenComplete)) { break; } waitNewUrl(); } else { Request requestFinal = request; this.threadPool.execute(new Runnable(requestFinal) { public void run() { try { Spider.this.processRequest(this.val$requestFinal); Spider.this.onSuccess(this.val$requestFinal); } catch (Exception e) { Spider.this.onError(this.val$requestFinal); Spider.this.logger.error("process request " + this.val$requestFinal + " error", e); } finally { Spider.this.pageCount.incrementAndGet(); Spider.this.signalNewUrl(); } } }); } } this.stat.set(2); if (this.destroyWhenExit) close();
上述中,由于Spider默認(rèn)exitWhenComplete=true,而this.threadPool.getThreadAlive() == 0也在我剛剛描述的場(chǎng)景中應(yīng)驗(yàn)了,所以此時(shí)Spider會(huì)break退出調(diào)度循環(huán),進(jìn)而終止。
那么如何解決呢?我們應(yīng)該注意到了exitWhenComplete這個(gè)標(biāo)志,Spider是開(kāi)放了這個(gè)標(biāo)志的setter的,那么我們可以通過(guò)它來(lái)實(shí)現(xiàn)自定義的管理。如何管理?
//設(shè)置exitWhenComplete=false,避免scheduler.poll返回null,且沒(méi)有工作線程時(shí)退出循環(huán)。 spider.setExitWhenComplete(false); spider.start(); //分頁(yè)循環(huán)推送url int i=2; while(i<=page.getTotalPages()){ page=storeManager.findPage(c, i, 50); for(Store s:page.getResult()){ if(StringUtils.isNotBlank(s.getSkipLink()) && s.getSkipLink().contains("?id=")){ Request request=new Request(s.getSkipLink()); scheduler.push(request,spider); } } i++; } int nullCount=0; //分5次重試來(lái)確保真的沒(méi)有了。 while(nullCount<5){ //如果沒(méi)有活動(dòng)線程,我們就查看scheduler中是否有request,如果沒(méi)有,計(jì)數(shù)+1,之后休眠再重新循環(huán)。 if(spider.getThreadAlive()==0){ Request req=scheduler.poll(spider); if(req==null){ nullCount++; }else{ if(nullCount>0){ nullCount=0; } scheduler.push(req, spider); } } HttpReqUtil.sleep(5*60*1000); } //退出檢測(cè)循環(huán)說(shuō)明結(jié)束了,手動(dòng)調(diào)用stop()來(lái)是Spider退出調(diào)度循環(huán),終止爬蟲(chóng)。 spider.stop();
其實(shí),如果你想Spider池化,也可以采用這個(gè)思路來(lái)。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/69916.html
摘要:爬蟲(chóng)框架源碼分析之爬蟲(chóng)框架源碼分析之爬蟲(chóng)框架源碼分析之爬蟲(chóng)框架源碼分析之爬蟲(chóng)框架源碼分析之之進(jìn)階 爬蟲(chóng)框架Webmagic源碼分析之Spider爬蟲(chóng)框架WebMagic源碼分析之Scheduler爬蟲(chóng)框架WebMagic源碼分析之Downloader爬蟲(chóng)框架WebMagic源碼分析之Selector爬蟲(chóng)框架WebMagic源碼分析之SeleniumWebMagic之Spider進(jìn)階
摘要:獲取正在運(yùn)行的線程數(shù),用于狀態(tài)監(jiān)控。之后初始化組件主要是初始化線程池將到中,初始化開(kāi)始時(shí)間等。如果線程池中運(yùn)行線程數(shù)量為,并且默認(rèn),那么就停止退出,結(jié)束爬蟲(chóng)。 本系列文章,針對(duì)Webmagic 0.6.1版本 一個(gè)普通爬蟲(chóng)啟動(dòng)代碼 public static void main(String[] args) { Spider.create(new GithubRepoPageP...
摘要:包主要實(shí)現(xiàn)類,這是一個(gè)抽象類,實(shí)現(xiàn)了通用的模板方法,并在方法內(nèi)部判斷錯(cuò)誤重試去重處理等。重置重復(fù)檢查就是清空,獲取請(qǐng)求總數(shù)也就是獲取的。至于請(qǐng)求總數(shù)統(tǒng)計(jì),就是返回中維護(hù)的的大小。 Scheduler是Webmagic中的url調(diào)度器,負(fù)責(zé)從Spider處理收集(push)需要抓取的url(Page的targetRequests)、并poll出將要被處理的url給Spider,同時(shí)還負(fù)責(zé)...
摘要:方法,首先判斷是否有這是在中配置的,如果有,直接調(diào)用的將相應(yīng)內(nèi)容轉(zhuǎn)化成對(duì)應(yīng)編碼字符串,否則智能檢測(cè)響應(yīng)內(nèi)容的字符編碼。 Downloader是負(fù)責(zé)請(qǐng)求url獲取返回值(html、json、jsonp等)的一個(gè)組件。當(dāng)然會(huì)同時(shí)處理POST重定向、Https驗(yàn)證、ip代理、判斷失敗重試等。 接口:Downloader 定義了download方法返回Page,定義了setThread方法來(lái)...
摘要:是爬蟲(chóng)框架中比較簡(jiǎn)單易上手的一個(gè)。官網(wǎng)鏈接下面的例子是使用這個(gè)框架來(lái)爬取工商銀行的私人理財(cái)推薦分頁(yè)列表數(shù)據(jù)。頁(yè)面鏈接為引入配置如果項(xiàng)目已經(jīng)引入記錄日志,則需要在中排除。 webmagic是java爬蟲(chóng)框架中比較簡(jiǎn)單易上手的一個(gè)。官網(wǎng)鏈接:http://webmagic.io/ 下面的例子是使用這個(gè)框架來(lái)爬取工商銀行的私人理財(cái)推薦分頁(yè)列表數(shù)據(jù)。頁(yè)面鏈接為:https://mybank.i...
閱讀 2989·2021-11-16 11:45
閱讀 5188·2021-09-22 10:57
閱讀 1775·2021-09-08 09:36
閱讀 1602·2021-09-02 15:40
閱讀 2517·2021-07-26 23:38
閱讀 1203·2019-08-30 15:55
閱讀 929·2019-08-30 15:54
閱讀 1220·2019-08-29 14:06