hash
網(wǎng)頁(yè)爬蟲(chóng)及其用到的算法和數據結構
采集交流 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 346 次瀏覽 ? 2020-05-13 08:04
網(wǎng)絡(luò )爬蟲(chóng)程序的好壞,很大程度上反映了一個(gè)搜索引擎的好差。不信,你可以隨意拿一個(gè)網(wǎng)站去查詢(xún)一下各家搜索對它的網(wǎng)頁(yè)收錄情況,爬蟲(chóng)強悍程度跟搜索引擎優(yōu)劣基本成正比。
1.世界上最簡(jiǎn)單的爬蟲(chóng)——三行情詩(shī)
我們先來(lái)看一個(gè)最簡(jiǎn)單的最簡(jiǎn)單的爬蟲(chóng),用python寫(xiě)成,只須要三行。
import requests url="http://www.cricode.com" r=requests.get(url)
上面這三行爬蟲(chóng)程序,就如下邊這三行短詩(shī)通常,很干脆利落。
是好男人,
就應當在和妻子爭吵時(shí)網(wǎng)絡(luò )爬蟲(chóng)算法書(shū)籍,
抱著(zhù)必輸的態(tài)度。
2.一個(gè)正常的爬蟲(chóng)程序
上面哪個(gè)最簡(jiǎn)單的爬蟲(chóng),是一個(gè)不完整的殘障的爬蟲(chóng)。因為爬蟲(chóng)程序一般須要做的事情如下:
因此,一個(gè)完整的爬蟲(chóng)大約是這樣子的:
import requests #用來(lái)爬取網(wǎng)頁(yè)
from bs4 import BeautifulSoup #用來(lái)解析網(wǎng)頁(yè)
seds = ["http://www.hao123.com", #我們的種子
"http://www.csdn.net",
http://www.cricode.com]
sum = 0 #我們設定終止條件為:爬取到100000個(gè)頁(yè)面時(shí),就不玩了
while sum < 10000 :
if sum < len(seds):
r = requests.get(seds[sum])
sum = sum + 1
do_save_action(r)
soup = BeautifulSoup(r.content)
urls = soup.find_all("href",.....) //解析網(wǎng)頁(yè)
for url in urls:
seds.append(url) else:
break
3.現在來(lái)找碴
上面哪個(gè)完整的爬蟲(chóng),不足20行代碼,相信你能找出20個(gè)茬來(lái)。因為它的缺點(diǎn)實(shí)在是太多。下面一一列出它的N宗罪:
4.找了這么多茬后,很有成就感,真正的問(wèn)題來(lái)了,學(xué)挖掘機究竟哪家強?
現在我們就來(lái)一一討論里面找碴找出的若干問(wèn)題的解決方案。
1)并行爬起問(wèn)題
我們可以有多重方式去實(shí)現并行。
多線(xiàn)程或則線(xiàn)程池形式,一個(gè)爬蟲(chóng)程序內部開(kāi)啟多個(gè)線(xiàn)程。同一臺機器開(kāi)啟多個(gè)爬蟲(chóng)程序,如此,我們就有N多爬取線(xiàn)程在同時(shí)工作。能大大降低時(shí)間。
此外,當我們要爬取的任務(wù)非常多時(shí),一臺機器、一個(gè)網(wǎng)點(diǎn)肯定是不夠的,我們必須考慮分布式爬蟲(chóng)。常見(jiàn)的分布式構架有:主從(Master——Slave)架構、點(diǎn)對點(diǎn)(PeertoPeer)架構,混合構架等。
說(shuō)道分布式構架,那我們須要考慮的問(wèn)題就有很多,我們須要分派任務(wù),各個(gè)爬蟲(chóng)之間須要通訊合作,共同完成任務(wù),不要重復爬取相同的網(wǎng)頁(yè)。分派任務(wù)我們要做到公正公平,就須要考慮怎樣進(jìn)行負載均衡。負載均衡,我們第一個(gè)想到的就是Hash,比如按照網(wǎng)站域名進(jìn)行hash。
負載均衡分派完任務(wù)以后,千萬(wàn)不要以為萬(wàn)事大吉了,萬(wàn)一哪臺機器掛了呢?原先委派給死掉的哪臺機器的任務(wù)委派給誰(shuí)?又或則哪天要降低幾臺機器網(wǎng)絡(luò )爬蟲(chóng)算法書(shū)籍,任務(wù)有該怎樣進(jìn)行重新分配呢?
一個(gè)比較好的解決方案是用一致性Hash算法。
2)待爬取網(wǎng)頁(yè)隊列
如何對待待抓取隊列,跟操作系統怎么調度進(jìn)程是類(lèi)似的場(chǎng)景。
不同網(wǎng)站,重要程度不同,因此,可以設計一個(gè)優(yōu)先級隊列來(lái)儲存待爬起的網(wǎng)頁(yè)鏈接。如此一來(lái),每次抓取時(shí),我們都優(yōu)先爬取重要的網(wǎng)頁(yè)。
當然,你也可以仿效操作系統的進(jìn)程調度策略之多級反饋隊列調度算法。
3)DNS緩存
為了防止每次都發(fā)起DNS查詢(xún),我們可以將DNS進(jìn)行緩存。DNS緩存其實(shí)是設計一個(gè)hash表來(lái)儲存已有的域名及其IP。
4)網(wǎng)頁(yè)去重
說(shuō)到網(wǎng)頁(yè)去重,第一個(gè)想到的是垃圾郵件過(guò)濾。垃圾郵件過(guò)濾一個(gè)精典的解決方案是BloomFilter(布隆過(guò)濾器)。布隆過(guò)濾器原理簡(jiǎn)單來(lái)說(shuō)就是:建立一個(gè)大的位字段,然后用多個(gè)Hash函數對同一個(gè)url進(jìn)行hash得到多個(gè)數字,然后將位字段中這種數字對應的位置為1。下次再來(lái)一個(gè)url時(shí),同樣是用多個(gè)Hash函數進(jìn)行hash,得到多個(gè)數字,我們只須要判定位字段中這種數字對應的為是全為1,如果全為1,那么說(shuō)明這個(gè)url早已出現過(guò)。如此,便完成了url去重的問(wèn)題。當然,這種方式會(huì )有偏差,只要偏差在我們的容忍范圍之類(lèi),比如1萬(wàn)個(gè)網(wǎng)頁(yè),我只爬取到了9999個(gè),剩下那一個(gè)網(wǎng)頁(yè),whocares!
5)數據儲存的問(wèn)題
數據儲存同樣是個(gè)挺有技術(shù)濃度的問(wèn)題。用關(guān)系數據庫存取還是用NoSQL,抑或是自己設計特定的文件格式進(jìn)行儲存,都大有文章可做。
6)進(jìn)程間通信
分布式爬蟲(chóng),就必然離不開(kāi)進(jìn)程間的通訊。我們可以以規定的數據格式進(jìn)行數據交互,完成進(jìn)程間通信。
7)……
廢話(huà)說(shuō)了那么多,真正的問(wèn)題來(lái)了,問(wèn)題不是學(xué)挖掘機究竟哪家強?而是怎么實(shí)現里面那些東西?。海?br /> 實(shí)現的過(guò)程中,你會(huì )發(fā)覺(jué),我們要考慮的問(wèn)題遠遠不止里面那些。紙上得來(lái)終覺(jué)淺,覺(jué)知此事要篤行! 查看全部

網(wǎng)絡(luò )爬蟲(chóng)程序的好壞,很大程度上反映了一個(gè)搜索引擎的好差。不信,你可以隨意拿一個(gè)網(wǎng)站去查詢(xún)一下各家搜索對它的網(wǎng)頁(yè)收錄情況,爬蟲(chóng)強悍程度跟搜索引擎優(yōu)劣基本成正比。
1.世界上最簡(jiǎn)單的爬蟲(chóng)——三行情詩(shī)
我們先來(lái)看一個(gè)最簡(jiǎn)單的最簡(jiǎn)單的爬蟲(chóng),用python寫(xiě)成,只須要三行。
import requests url="http://www.cricode.com" r=requests.get(url)
上面這三行爬蟲(chóng)程序,就如下邊這三行短詩(shī)通常,很干脆利落。
是好男人,
就應當在和妻子爭吵時(shí)網(wǎng)絡(luò )爬蟲(chóng)算法書(shū)籍,
抱著(zhù)必輸的態(tài)度。
2.一個(gè)正常的爬蟲(chóng)程序
上面哪個(gè)最簡(jiǎn)單的爬蟲(chóng),是一個(gè)不完整的殘障的爬蟲(chóng)。因為爬蟲(chóng)程序一般須要做的事情如下:
因此,一個(gè)完整的爬蟲(chóng)大約是這樣子的:
import requests #用來(lái)爬取網(wǎng)頁(yè)
from bs4 import BeautifulSoup #用來(lái)解析網(wǎng)頁(yè)
seds = ["http://www.hao123.com", #我們的種子
"http://www.csdn.net",
http://www.cricode.com]
sum = 0 #我們設定終止條件為:爬取到100000個(gè)頁(yè)面時(shí),就不玩了
while sum < 10000 :
if sum < len(seds):
r = requests.get(seds[sum])
sum = sum + 1
do_save_action(r)
soup = BeautifulSoup(r.content)
urls = soup.find_all("href",.....) //解析網(wǎng)頁(yè)
for url in urls:
seds.append(url) else:
break
3.現在來(lái)找碴
上面哪個(gè)完整的爬蟲(chóng),不足20行代碼,相信你能找出20個(gè)茬來(lái)。因為它的缺點(diǎn)實(shí)在是太多。下面一一列出它的N宗罪:
4.找了這么多茬后,很有成就感,真正的問(wèn)題來(lái)了,學(xué)挖掘機究竟哪家強?
現在我們就來(lái)一一討論里面找碴找出的若干問(wèn)題的解決方案。
1)并行爬起問(wèn)題
我們可以有多重方式去實(shí)現并行。
多線(xiàn)程或則線(xiàn)程池形式,一個(gè)爬蟲(chóng)程序內部開(kāi)啟多個(gè)線(xiàn)程。同一臺機器開(kāi)啟多個(gè)爬蟲(chóng)程序,如此,我們就有N多爬取線(xiàn)程在同時(shí)工作。能大大降低時(shí)間。
此外,當我們要爬取的任務(wù)非常多時(shí),一臺機器、一個(gè)網(wǎng)點(diǎn)肯定是不夠的,我們必須考慮分布式爬蟲(chóng)。常見(jiàn)的分布式構架有:主從(Master——Slave)架構、點(diǎn)對點(diǎn)(PeertoPeer)架構,混合構架等。
說(shuō)道分布式構架,那我們須要考慮的問(wèn)題就有很多,我們須要分派任務(wù),各個(gè)爬蟲(chóng)之間須要通訊合作,共同完成任務(wù),不要重復爬取相同的網(wǎng)頁(yè)。分派任務(wù)我們要做到公正公平,就須要考慮怎樣進(jìn)行負載均衡。負載均衡,我們第一個(gè)想到的就是Hash,比如按照網(wǎng)站域名進(jìn)行hash。
負載均衡分派完任務(wù)以后,千萬(wàn)不要以為萬(wàn)事大吉了,萬(wàn)一哪臺機器掛了呢?原先委派給死掉的哪臺機器的任務(wù)委派給誰(shuí)?又或則哪天要降低幾臺機器網(wǎng)絡(luò )爬蟲(chóng)算法書(shū)籍,任務(wù)有該怎樣進(jìn)行重新分配呢?
一個(gè)比較好的解決方案是用一致性Hash算法。
2)待爬取網(wǎng)頁(yè)隊列
如何對待待抓取隊列,跟操作系統怎么調度進(jìn)程是類(lèi)似的場(chǎng)景。
不同網(wǎng)站,重要程度不同,因此,可以設計一個(gè)優(yōu)先級隊列來(lái)儲存待爬起的網(wǎng)頁(yè)鏈接。如此一來(lái),每次抓取時(shí),我們都優(yōu)先爬取重要的網(wǎng)頁(yè)。
當然,你也可以仿效操作系統的進(jìn)程調度策略之多級反饋隊列調度算法。
3)DNS緩存
為了防止每次都發(fā)起DNS查詢(xún),我們可以將DNS進(jìn)行緩存。DNS緩存其實(shí)是設計一個(gè)hash表來(lái)儲存已有的域名及其IP。
4)網(wǎng)頁(yè)去重
說(shuō)到網(wǎng)頁(yè)去重,第一個(gè)想到的是垃圾郵件過(guò)濾。垃圾郵件過(guò)濾一個(gè)精典的解決方案是BloomFilter(布隆過(guò)濾器)。布隆過(guò)濾器原理簡(jiǎn)單來(lái)說(shuō)就是:建立一個(gè)大的位字段,然后用多個(gè)Hash函數對同一個(gè)url進(jìn)行hash得到多個(gè)數字,然后將位字段中這種數字對應的位置為1。下次再來(lái)一個(gè)url時(shí),同樣是用多個(gè)Hash函數進(jìn)行hash,得到多個(gè)數字,我們只須要判定位字段中這種數字對應的為是全為1,如果全為1,那么說(shuō)明這個(gè)url早已出現過(guò)。如此,便完成了url去重的問(wèn)題。當然,這種方式會(huì )有偏差,只要偏差在我們的容忍范圍之類(lèi),比如1萬(wàn)個(gè)網(wǎng)頁(yè),我只爬取到了9999個(gè),剩下那一個(gè)網(wǎng)頁(yè),whocares!
5)數據儲存的問(wèn)題
數據儲存同樣是個(gè)挺有技術(shù)濃度的問(wèn)題。用關(guān)系數據庫存取還是用NoSQL,抑或是自己設計特定的文件格式進(jìn)行儲存,都大有文章可做。
6)進(jìn)程間通信
分布式爬蟲(chóng),就必然離不開(kāi)進(jìn)程間的通訊。我們可以以規定的數據格式進(jìn)行數據交互,完成進(jìn)程間通信。
7)……
廢話(huà)說(shuō)了那么多,真正的問(wèn)題來(lái)了,問(wèn)題不是學(xué)挖掘機究竟哪家強?而是怎么實(shí)現里面那些東西?。海?br /> 實(shí)現的過(guò)程中,你會(huì )發(fā)覺(jué),我們要考慮的問(wèn)題遠遠不止里面那些。紙上得來(lái)終覺(jué)淺,覺(jué)知此事要篤行!
網(wǎng)頁(yè)爬蟲(chóng)及其用到的算法和數據結構
采集交流 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 346 次瀏覽 ? 2020-05-13 08:04
網(wǎng)絡(luò )爬蟲(chóng)程序的好壞,很大程度上反映了一個(gè)搜索引擎的好差。不信,你可以隨意拿一個(gè)網(wǎng)站去查詢(xún)一下各家搜索對它的網(wǎng)頁(yè)收錄情況,爬蟲(chóng)強悍程度跟搜索引擎優(yōu)劣基本成正比。
1.世界上最簡(jiǎn)單的爬蟲(chóng)——三行情詩(shī)
我們先來(lái)看一個(gè)最簡(jiǎn)單的最簡(jiǎn)單的爬蟲(chóng),用python寫(xiě)成,只須要三行。
import requests url="http://www.cricode.com" r=requests.get(url)
上面這三行爬蟲(chóng)程序,就如下邊這三行短詩(shī)通常,很干脆利落。
是好男人,
就應當在和妻子爭吵時(shí)網(wǎng)絡(luò )爬蟲(chóng)算法書(shū)籍,
抱著(zhù)必輸的態(tài)度。
2.一個(gè)正常的爬蟲(chóng)程序
上面哪個(gè)最簡(jiǎn)單的爬蟲(chóng),是一個(gè)不完整的殘障的爬蟲(chóng)。因為爬蟲(chóng)程序一般須要做的事情如下:
因此,一個(gè)完整的爬蟲(chóng)大約是這樣子的:
import requests #用來(lái)爬取網(wǎng)頁(yè)
from bs4 import BeautifulSoup #用來(lái)解析網(wǎng)頁(yè)
seds = ["http://www.hao123.com", #我們的種子
"http://www.csdn.net",
http://www.cricode.com]
sum = 0 #我們設定終止條件為:爬取到100000個(gè)頁(yè)面時(shí),就不玩了
while sum < 10000 :
if sum < len(seds):
r = requests.get(seds[sum])
sum = sum + 1
do_save_action(r)
soup = BeautifulSoup(r.content)
urls = soup.find_all("href",.....) //解析網(wǎng)頁(yè)
for url in urls:
seds.append(url) else:
break
3.現在來(lái)找碴
上面哪個(gè)完整的爬蟲(chóng),不足20行代碼,相信你能找出20個(gè)茬來(lái)。因為它的缺點(diǎn)實(shí)在是太多。下面一一列出它的N宗罪:
4.找了這么多茬后,很有成就感,真正的問(wèn)題來(lái)了,學(xué)挖掘機究竟哪家強?
現在我們就來(lái)一一討論里面找碴找出的若干問(wèn)題的解決方案。
1)并行爬起問(wèn)題
我們可以有多重方式去實(shí)現并行。
多線(xiàn)程或則線(xiàn)程池形式,一個(gè)爬蟲(chóng)程序內部開(kāi)啟多個(gè)線(xiàn)程。同一臺機器開(kāi)啟多個(gè)爬蟲(chóng)程序,如此,我們就有N多爬取線(xiàn)程在同時(shí)工作。能大大降低時(shí)間。
此外,當我們要爬取的任務(wù)非常多時(shí),一臺機器、一個(gè)網(wǎng)點(diǎn)肯定是不夠的,我們必須考慮分布式爬蟲(chóng)。常見(jiàn)的分布式構架有:主從(Master——Slave)架構、點(diǎn)對點(diǎn)(PeertoPeer)架構,混合構架等。
說(shuō)道分布式構架,那我們須要考慮的問(wèn)題就有很多,我們須要分派任務(wù),各個(gè)爬蟲(chóng)之間須要通訊合作,共同完成任務(wù),不要重復爬取相同的網(wǎng)頁(yè)。分派任務(wù)我們要做到公正公平,就須要考慮怎樣進(jìn)行負載均衡。負載均衡,我們第一個(gè)想到的就是Hash,比如按照網(wǎng)站域名進(jìn)行hash。
負載均衡分派完任務(wù)以后,千萬(wàn)不要以為萬(wàn)事大吉了,萬(wàn)一哪臺機器掛了呢?原先委派給死掉的哪臺機器的任務(wù)委派給誰(shuí)?又或則哪天要降低幾臺機器網(wǎng)絡(luò )爬蟲(chóng)算法書(shū)籍,任務(wù)有該怎樣進(jìn)行重新分配呢?
一個(gè)比較好的解決方案是用一致性Hash算法。
2)待爬取網(wǎng)頁(yè)隊列
如何對待待抓取隊列,跟操作系統怎么調度進(jìn)程是類(lèi)似的場(chǎng)景。
不同網(wǎng)站,重要程度不同,因此,可以設計一個(gè)優(yōu)先級隊列來(lái)儲存待爬起的網(wǎng)頁(yè)鏈接。如此一來(lái),每次抓取時(shí),我們都優(yōu)先爬取重要的網(wǎng)頁(yè)。
當然,你也可以仿效操作系統的進(jìn)程調度策略之多級反饋隊列調度算法。
3)DNS緩存
為了防止每次都發(fā)起DNS查詢(xún),我們可以將DNS進(jìn)行緩存。DNS緩存其實(shí)是設計一個(gè)hash表來(lái)儲存已有的域名及其IP。
4)網(wǎng)頁(yè)去重
說(shuō)到網(wǎng)頁(yè)去重,第一個(gè)想到的是垃圾郵件過(guò)濾。垃圾郵件過(guò)濾一個(gè)精典的解決方案是BloomFilter(布隆過(guò)濾器)。布隆過(guò)濾器原理簡(jiǎn)單來(lái)說(shuō)就是:建立一個(gè)大的位字段,然后用多個(gè)Hash函數對同一個(gè)url進(jìn)行hash得到多個(gè)數字,然后將位字段中這種數字對應的位置為1。下次再來(lái)一個(gè)url時(shí),同樣是用多個(gè)Hash函數進(jìn)行hash,得到多個(gè)數字,我們只須要判定位字段中這種數字對應的為是全為1,如果全為1,那么說(shuō)明這個(gè)url早已出現過(guò)。如此,便完成了url去重的問(wèn)題。當然,這種方式會(huì )有偏差,只要偏差在我們的容忍范圍之類(lèi),比如1萬(wàn)個(gè)網(wǎng)頁(yè),我只爬取到了9999個(gè),剩下那一個(gè)網(wǎng)頁(yè),whocares!
5)數據儲存的問(wèn)題
數據儲存同樣是個(gè)挺有技術(shù)濃度的問(wèn)題。用關(guān)系數據庫存取還是用NoSQL,抑或是自己設計特定的文件格式進(jìn)行儲存,都大有文章可做。
6)進(jìn)程間通信
分布式爬蟲(chóng),就必然離不開(kāi)進(jìn)程間的通訊。我們可以以規定的數據格式進(jìn)行數據交互,完成進(jìn)程間通信。
7)……
廢話(huà)說(shuō)了那么多,真正的問(wèn)題來(lái)了,問(wèn)題不是學(xué)挖掘機究竟哪家強?而是怎么實(shí)現里面那些東西?。海?br /> 實(shí)現的過(guò)程中,你會(huì )發(fā)覺(jué),我們要考慮的問(wèn)題遠遠不止里面那些。紙上得來(lái)終覺(jué)淺,覺(jué)知此事要篤行! 查看全部

網(wǎng)絡(luò )爬蟲(chóng)程序的好壞,很大程度上反映了一個(gè)搜索引擎的好差。不信,你可以隨意拿一個(gè)網(wǎng)站去查詢(xún)一下各家搜索對它的網(wǎng)頁(yè)收錄情況,爬蟲(chóng)強悍程度跟搜索引擎優(yōu)劣基本成正比。
1.世界上最簡(jiǎn)單的爬蟲(chóng)——三行情詩(shī)
我們先來(lái)看一個(gè)最簡(jiǎn)單的最簡(jiǎn)單的爬蟲(chóng),用python寫(xiě)成,只須要三行。
import requests url="http://www.cricode.com" r=requests.get(url)
上面這三行爬蟲(chóng)程序,就如下邊這三行短詩(shī)通常,很干脆利落。
是好男人,
就應當在和妻子爭吵時(shí)網(wǎng)絡(luò )爬蟲(chóng)算法書(shū)籍,
抱著(zhù)必輸的態(tài)度。
2.一個(gè)正常的爬蟲(chóng)程序
上面哪個(gè)最簡(jiǎn)單的爬蟲(chóng),是一個(gè)不完整的殘障的爬蟲(chóng)。因為爬蟲(chóng)程序一般須要做的事情如下:
因此,一個(gè)完整的爬蟲(chóng)大約是這樣子的:
import requests #用來(lái)爬取網(wǎng)頁(yè)
from bs4 import BeautifulSoup #用來(lái)解析網(wǎng)頁(yè)
seds = ["http://www.hao123.com", #我們的種子
"http://www.csdn.net",
http://www.cricode.com]
sum = 0 #我們設定終止條件為:爬取到100000個(gè)頁(yè)面時(shí),就不玩了
while sum < 10000 :
if sum < len(seds):
r = requests.get(seds[sum])
sum = sum + 1
do_save_action(r)
soup = BeautifulSoup(r.content)
urls = soup.find_all("href",.....) //解析網(wǎng)頁(yè)
for url in urls:
seds.append(url) else:
break
3.現在來(lái)找碴
上面哪個(gè)完整的爬蟲(chóng),不足20行代碼,相信你能找出20個(gè)茬來(lái)。因為它的缺點(diǎn)實(shí)在是太多。下面一一列出它的N宗罪:
4.找了這么多茬后,很有成就感,真正的問(wèn)題來(lái)了,學(xué)挖掘機究竟哪家強?
現在我們就來(lái)一一討論里面找碴找出的若干問(wèn)題的解決方案。
1)并行爬起問(wèn)題
我們可以有多重方式去實(shí)現并行。
多線(xiàn)程或則線(xiàn)程池形式,一個(gè)爬蟲(chóng)程序內部開(kāi)啟多個(gè)線(xiàn)程。同一臺機器開(kāi)啟多個(gè)爬蟲(chóng)程序,如此,我們就有N多爬取線(xiàn)程在同時(shí)工作。能大大降低時(shí)間。
此外,當我們要爬取的任務(wù)非常多時(shí),一臺機器、一個(gè)網(wǎng)點(diǎn)肯定是不夠的,我們必須考慮分布式爬蟲(chóng)。常見(jiàn)的分布式構架有:主從(Master——Slave)架構、點(diǎn)對點(diǎn)(PeertoPeer)架構,混合構架等。
說(shuō)道分布式構架,那我們須要考慮的問(wèn)題就有很多,我們須要分派任務(wù),各個(gè)爬蟲(chóng)之間須要通訊合作,共同完成任務(wù),不要重復爬取相同的網(wǎng)頁(yè)。分派任務(wù)我們要做到公正公平,就須要考慮怎樣進(jìn)行負載均衡。負載均衡,我們第一個(gè)想到的就是Hash,比如按照網(wǎng)站域名進(jìn)行hash。
負載均衡分派完任務(wù)以后,千萬(wàn)不要以為萬(wàn)事大吉了,萬(wàn)一哪臺機器掛了呢?原先委派給死掉的哪臺機器的任務(wù)委派給誰(shuí)?又或則哪天要降低幾臺機器網(wǎng)絡(luò )爬蟲(chóng)算法書(shū)籍,任務(wù)有該怎樣進(jìn)行重新分配呢?
一個(gè)比較好的解決方案是用一致性Hash算法。
2)待爬取網(wǎng)頁(yè)隊列
如何對待待抓取隊列,跟操作系統怎么調度進(jìn)程是類(lèi)似的場(chǎng)景。
不同網(wǎng)站,重要程度不同,因此,可以設計一個(gè)優(yōu)先級隊列來(lái)儲存待爬起的網(wǎng)頁(yè)鏈接。如此一來(lái),每次抓取時(shí),我們都優(yōu)先爬取重要的網(wǎng)頁(yè)。
當然,你也可以仿效操作系統的進(jìn)程調度策略之多級反饋隊列調度算法。
3)DNS緩存
為了防止每次都發(fā)起DNS查詢(xún),我們可以將DNS進(jìn)行緩存。DNS緩存其實(shí)是設計一個(gè)hash表來(lái)儲存已有的域名及其IP。
4)網(wǎng)頁(yè)去重
說(shuō)到網(wǎng)頁(yè)去重,第一個(gè)想到的是垃圾郵件過(guò)濾。垃圾郵件過(guò)濾一個(gè)精典的解決方案是BloomFilter(布隆過(guò)濾器)。布隆過(guò)濾器原理簡(jiǎn)單來(lái)說(shuō)就是:建立一個(gè)大的位字段,然后用多個(gè)Hash函數對同一個(gè)url進(jìn)行hash得到多個(gè)數字,然后將位字段中這種數字對應的位置為1。下次再來(lái)一個(gè)url時(shí),同樣是用多個(gè)Hash函數進(jìn)行hash,得到多個(gè)數字,我們只須要判定位字段中這種數字對應的為是全為1,如果全為1,那么說(shuō)明這個(gè)url早已出現過(guò)。如此,便完成了url去重的問(wèn)題。當然,這種方式會(huì )有偏差,只要偏差在我們的容忍范圍之類(lèi),比如1萬(wàn)個(gè)網(wǎng)頁(yè),我只爬取到了9999個(gè),剩下那一個(gè)網(wǎng)頁(yè),whocares!
5)數據儲存的問(wèn)題
數據儲存同樣是個(gè)挺有技術(shù)濃度的問(wèn)題。用關(guān)系數據庫存取還是用NoSQL,抑或是自己設計特定的文件格式進(jìn)行儲存,都大有文章可做。
6)進(jìn)程間通信
分布式爬蟲(chóng),就必然離不開(kāi)進(jìn)程間的通訊。我們可以以規定的數據格式進(jìn)行數據交互,完成進(jìn)程間通信。
7)……
廢話(huà)說(shuō)了那么多,真正的問(wèn)題來(lái)了,問(wèn)題不是學(xué)挖掘機究竟哪家強?而是怎么實(shí)現里面那些東西?。海?br /> 實(shí)現的過(guò)程中,你會(huì )發(fā)覺(jué),我們要考慮的問(wèn)題遠遠不止里面那些。紙上得來(lái)終覺(jué)淺,覺(jué)知此事要篤行!


