java多线程爬虫_Java 多线程爬虫及分布式爬虫架构
在這個(gè)時(shí)間就是金錢的年代,不可能給你時(shí)間去慢慢的采集,所以單線程爬蟲(chóng)程序是行不通的,我們需要將單線程改成多線程的模式,來(lái)提升采集效率和提高計(jì)算機(jī)利用率。維護(hù)待采集的 URL多線程爬蟲(chóng)程序就不能像單線程那樣,每個(gè)線程獨(dú)自維護(hù)這自己的待采集 URL,如果這樣的話,那么每個(gè)線程采集的網(wǎng)頁(yè)將是一樣的,你這就不是多線程采集啦,你這是將一個(gè)頁(yè)面采集的多次。
正文
在人們調(diào)節(jié)爬蟲(chóng)程序的那時(shí)候,單線程網(wǎng)絡(luò)爬蟲(chóng)沒(méi)有什么難題,但是當(dāng)我們?cè)诰€上環(huán)境使用單線程爬蟲(chóng)程序去采集網(wǎng)頁(yè)時(shí),單線程就普遍存在了2個(gè)致命性的難題:
采集高效率非常慢,單線程中間全是串行的,下一個(gè)執(zhí)行動(dòng)作需要等上一個(gè)執(zhí)行完才能執(zhí)行。
對(duì)網(wǎng)絡(luò)服務(wù)器的CUP等使用率不高,想著人們的網(wǎng)絡(luò)服務(wù)器全是 8核16G,32G 的只跑一個(gè)線程會(huì)否太奢侈浪費(fèi)
網(wǎng)上自然環(huán)境不太可能像人們當(dāng)?shù)貦z測(cè)一樣,不在意采集高效率,要是能恰當(dāng)獲取結(jié)果就行。在這一時(shí)間就是生命的時(shí)代,不太可能讓你時(shí)間去漸漸地的采集,因此單線程爬蟲(chóng)程序是難以實(shí)現(xiàn)的,人們必須將單線程改為多核的方式,來(lái)提高采集高效率和提升電腦使用率。
多核的爬蟲(chóng)程序設(shè)計(jì)方案比單線程還要繁雜許多,可是與別的業(yè)務(wù)流程在分布式系統(tǒng)下要確保信息安全又不一樣,多核網(wǎng)絡(luò)爬蟲(chóng)在信息安全上升規(guī)定并不是那麼的高,由于每一網(wǎng)頁(yè)頁(yè)面能夠被當(dāng)作是一個(gè)單獨(dú)體。要搞好多核網(wǎng)絡(luò)爬蟲(chóng)就務(wù)必搞好二點(diǎn):第一點(diǎn)就是說(shuō)統(tǒng)一的待采集 URL 維護(hù),第二點(diǎn)就是說(shuō) URL 的去重, 下邊人們簡(jiǎn)易的來(lái)聊一聊這個(gè)方面。
維護(hù)待采集的 URL
多核爬蟲(chóng)程序就不可以像單線程那般,每一線程獨(dú)自一人維護(hù)這自身的待采集 URL,假如那樣的話,那麼每一線程采集的網(wǎng)頁(yè)頁(yè)面將是一樣的,你這就并不是多核采集啦,你它是將一個(gè)網(wǎng)頁(yè)頁(yè)面采集的數(shù)次。根據(jù)這一緣故人們就必須將待采集的 URL 統(tǒng)一維護(hù),每一線程從統(tǒng)一 URL 維護(hù)處領(lǐng)到采集 URL ,進(jìn)行采集每日任務(wù),假如在網(wǎng)頁(yè)頁(yè)面上發(fā)覺(jué)新的 URL 連接則加上到 統(tǒng)一 URL 維護(hù)的器皿中。下邊是幾類合適用來(lái)統(tǒng)一 URL 維護(hù)的器皿:JDK 的安全性序列,比如 LinkedBlockingQueue
性能的 NoSQL,例如 Redis、Mongodb
MQ 消息中間件
URL 的去重
URL 的去重都是多核采集的重要一步,由于假如沒(méi)去重得話,那麼人們將采集到很多反復(fù)的 URL,那樣并沒(méi)有提高人們的采集高效率,例如一個(gè)分頁(yè)查詢的新聞報(bào)道目錄,人們?cè)诓杉谝豁?yè)的那時(shí)候能夠獲得 2、3、4、5 頁(yè)的連接,在采集第二頁(yè)的那時(shí)候又會(huì)獲得 1、3、4、5 頁(yè)的連接,待采集的 URL 序列軍委委員存有很多的搜索結(jié)果頁(yè)連接,那樣就會(huì)反復(fù)采集以至于進(jìn)到到一個(gè)無(wú)限循環(huán)之中,因此就必須 URL 去重。URL 去重的方式就十分多啦,下邊是幾類常見(jiàn)的 URL 去重方法:將 URL 儲(chǔ)存到數(shù)據(jù)庫(kù)查詢開(kāi)展去重,例如 redis、MongoDB
將 URL 放進(jìn)哈希表中去重,比如 hashset
將 URL 經(jīng)過(guò) MD5 之后保存到哈希表中去重,相比于上面一種,能夠節(jié)約空間
使用 布隆過(guò)濾器(Bloom Filter)去重,這種方式能夠節(jié)約大量的空間,就是不那么準(zhǔn)確。
關(guān)于多線程爬蟲(chóng)的兩個(gè)核心知識(shí)點(diǎn)我們都知道啦,下面我畫(huà)了一個(gè)簡(jiǎn)單的多線程爬蟲(chóng)架構(gòu)圖,如下圖所示:
多線程爬蟲(chóng)架構(gòu)圖
上面我們主要了解了多線程爬蟲(chóng)的架構(gòu)設(shè)計(jì),接下來(lái)我們不妨來(lái)試試 Java 多線程爬蟲(chóng),我們以采集虎撲新聞為例來(lái)實(shí)戰(zhàn)一下 Java 多線程爬蟲(chóng),Java 多線程爬蟲(chóng)中設(shè)計(jì)到了 待采集 URL 的維護(hù)和 URL 去重,由于我們這里只是演示,所以我們就使用 JDK 內(nèi)置的容器來(lái)完成,我們使用 LinkedBlockingQueue 作為待采集 URL 維護(hù)容器,HashSet 作為 URL 去重容器。下面是 Java 多線程爬蟲(chóng)核心代碼,詳細(xì)代碼以上傳 GitHub,地址在文末:
我們用 5 個(gè)線程去采集虎撲新聞列表頁(yè)看看效果如果?運(yùn)行該程序,得到如下結(jié)果:
多線程采集結(jié)果
結(jié)果中可以看出,我們啟動(dòng)了 5 個(gè)線程采集了 61 頁(yè)頁(yè)面,一共耗時(shí) 2 秒鐘,可以說(shuō)效果還是不錯(cuò)的,我們來(lái)跟單線程對(duì)比一下,看看差距有多大?我們將線程數(shù)設(shè)置為 1 ,再次啟動(dòng)程序,得到如下結(jié)果:
單線程運(yùn)行結(jié)果
可以看出單線程采集虎撲 61 條新聞花費(fèi)了 7 秒鐘,耗時(shí)差不多是多線程的 4 倍,你想想這可只是 61 個(gè)頁(yè)面,頁(yè)面更多的話,差距會(huì)越來(lái)越大,所以多線程爬蟲(chóng)效率還是非常高的。
分布式爬蟲(chóng)架構(gòu)
分布式爬蟲(chóng)架構(gòu)是一個(gè)大型采集程序才需要使用的架構(gòu),一般情況下使用單機(jī)多線程就可以解決業(yè)務(wù)需求,反正我是沒(méi)有分布式爬蟲(chóng)項(xiàng)目的經(jīng)驗(yàn),所以這一塊我也沒(méi)什么可以講的,但是我們作為技術(shù)人員,我們需要對(duì)技術(shù)保存熱度,雖然不用,但是了解了解也無(wú)妨,我查閱了不少資料得出了如下結(jié)論:
分布式爬蟲(chóng)架構(gòu)跟我們多線程爬蟲(chóng)架構(gòu)在思路上來(lái)說(shuō)是一樣的,我們只需要在多線程的基礎(chǔ)上稍加改進(jìn)就可以變成一個(gè)簡(jiǎn)單的分布式爬蟲(chóng)架構(gòu)。因?yàn)榉植际脚老x(chóng)架構(gòu)中爬蟲(chóng)程序部署在不同的機(jī)器上,所以我們待采集的 URL 和 采集過(guò)的 URL 就不能存放在爬蟲(chóng)程序機(jī)器的內(nèi)存中啦,我們需要將它統(tǒng)一在某臺(tái)機(jī)器上維護(hù)啦,比如存放在 Redis 或者 MongoDB 中,每臺(tái)機(jī)器都從這上面獲取采集鏈接,而不是從 LinkedBlockingQueue 這樣的內(nèi)存隊(duì)列中取鏈接啦,這樣一個(gè)簡(jiǎn)單的分布式爬蟲(chóng)架構(gòu)就出現(xiàn)了,當(dāng)然這里面還會(huì)有很多細(xì)節(jié)問(wèn)題,因?yàn)槲覜](méi)有分布式架構(gòu)的經(jīng)驗(yàn)
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來(lái)咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)總結(jié)
以上是生活随笔為你收集整理的java多线程爬虫_Java 多线程爬虫及分布式爬虫架构的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 二分法分页 mysql_LeetCode
- 下一篇: 研华电脑510上电自启_研华工控机怎么设