當前位置:名人名言大全網 - 笑話大全 - 如何使用Python作為爬行動物

如何使用Python作為爬行動物

1)首先,妳得明白爬行動物是怎麽工作的。

想象妳是壹只蜘蛛,現在妳被放到了互聯網上。然後,妳需要閱讀所有的網頁。我們做什麽呢沒問題,只是從某個地方開始,例如,人民日報的主頁,它被稱為初始頁面,它由$表示

在人民日報的主頁上,妳可以看到頁面所指向的各種鏈接。於是妳開心地從“國內新聞”頁面爬到了。太好了,所以妳已經爬了兩頁了(首頁和國內新聞)!暫且不管抓取的頁面是如何處理的,就想象妳把這個頁面復制成壹個html,放在妳身上。

突然妳發現國內新聞頁面上有壹個回到“首頁”的鏈接。作為壹只聰明的蜘蛛,妳壹定知道妳不用爬回去,因為妳已經看到了。所以,妳需要動動腦子,把妳看過的頁面地址保存下來。這樣,每看到壹個可能需要妳去爬的新鏈接,妳都要先在腦海裏檢查壹下自己是否去過這個頁面地址。如果有,就不要去。

好吧,理論上,如果能從初始頁面到達所有頁面,就能證明妳壹定能爬上所有頁面。

那麽如何用python實現呢?

非常簡單

導入隊列

Initial_page = "初始化頁面"

url_queue = Queue。隊列()

seen = set()

seen.insert(initial_page)

url_queue.put(initial_page)

While(真):#壹直走下去,直到海枯石爛。

if URL _ queue . size()& gt;0:

Current_url = url_queue.get() #取出隊列中第壹個的url。

Store(current_url) #存儲由該url表示的網頁。

對於extract _ urls (current _ url)中的next _ url選擇鏈接此URL的URL。

如果看不到下壹個url:

seen.put(next_url)

url_queue.put(next_url)

否則:

破裂

已經是偽代碼了。

所有爬行動物的脊椎都在這裏。我們來分析壹下為什麽爬蟲其實是壹個很復雜的東西——搜索引擎公司通常會有壹整個團隊來維護和開發它們。

2)效率

如果直接處理上面的代碼,直接運行,妳要花整整壹年的時間才能爬下整個豆瓣內容。更不用說Google這樣的搜索引擎需要抓取全網的內容。

有什麽問題?要爬的頁面太多,上面的代碼太慢。假設全網有N個網站,那麽判斷重復的復雜度是N*log(N),因為所有網頁都需要遍歷壹次,每次重復判斷set都要花費log(N)的復雜度。好了好了,我知道python的set實現是hash的——但是還是太慢了,至少內存使用效率不高。

量刑的慣例是什麽?布魯姆過濾器。簡單來說,它還是壹種hash方法,但它的特點是可以使用固定內存(不隨URL個數增加)以O(1)的效率確定URL是否已經在集合中。不幸的是,天下沒有免費的午餐。它唯壹的問題是,如果這個url不在集合中,BF可以100%確定這個url沒有被看到過。但是如果這個網址在集合裏,它會告訴妳這個網址應該已經出現了,但是我有2%的不確定性。請註意,當您分配的內存足夠大時,這裏的不確定性會變得非常小。壹個簡單的教程:布隆過濾器的例子

註意這個特點,如果網址已經看過,可能小概率會重復(沒關系,多看幾眼也死不了)。但如果妳沒看過,妳肯定會被看到(這點很重要,否則我們會錯過壹些網頁!)。【重要提示:本段有問題,請暫時跳過】

好了,現在我們已經接近處理重量判斷的最快方法了。另壹個瓶頸——妳只有壹臺機器。不管妳的帶寬有多大,只要妳的機器下載網頁的速度是瓶頸,那麽妳就要加快這個速度。如果壹臺機器不夠,使用多臺!當然,讓我們假設每臺機器都發揮了最大效率——使用多線程(在python中是多進程)。

3)集群抓取

爬豆瓣的時候,我總是用100多臺機器晝夜不停的跑壹個月。試想壹下,如果只用壹臺機器,就要運行100個月。...

那麽,假設妳現在有100臺機器可用,如何用python實現壹個分布式的爬行算法呢?

我們調用100臺計算能力低的機器中的99臺作為從機,另壹臺計算能力大的機器作為主機,所以復習壹下上面代碼中的url_queue。如果能把這個隊列放在這個主機上,所有的從機都可以通過網絡和主機通信。每當從機下載完壹個網頁,它都會向主機請求壹個新的網頁來抓取它。並且slave每捕捉到壹個新的網頁,就把這個網頁上的所有鏈接發送到master的隊列中。同樣的,bloom filter也放在master上,但是現在master只發送沒有訪問過的URL給slave。Bloom Filter放在master的內存中,訪問的url放在運行在master上的Redis中,這樣就保證了所有操作都是O(1)。(至少平均份額為O(1),Redis的訪問效率如:Lin sert–Redis所示)。

考慮如何用python實現它:

如果在每個從機上安裝scrapy,那麽每臺機器就成為壹個具有爬行能力的從機,Redis和rq作為分布式隊列安裝在主機上。

然後編寫代碼

#slave.py

current_url =請求來自主機()

to_send = []

對於提取url(當前url)中的下壹個URL:

to_send.append(next_url)

store(current _ URL);

發送到主機

#master.py

分布式隊列=分布式隊列()

bf = BloomFilter()

initial _ pages = " www . renming ribao . com "

while(True):

if request == 'GET ':

if distributed_queue.size()>0:

發送(distributed_queue.get())

否則:

破裂

elif request == 'POST ':

bf.put(request.url)

好了,其實妳可以想象,已經有人寫出了妳需要的東西:Darkho/Scrapy-Redis Github。

4)展望和後處理

雖然上面用了很多“簡單”,但是要實現壹個商用的爬蟲並不容易。上面的代碼用來爬壹整個網站問題不大。

但是如果加上這些後續治療,比如

有效存儲(應該如何安排數據庫)

有效判斷權重(這裏指的是網頁,我們不想爬人民日報和抄襲它的大人民日報)

有效的信息提取(比如如何提取網頁上的所有地址“朝陽區奮進路中華路”),搜索引擎通常不需要存儲所有的信息,比如我為什麽要保存圖片?...

及時更新(預測該頁面的更新頻率)

可想而知,這裏的每壹點,都可以被很多研究者研究十幾年。即便如此,

“路漫漫其修遠兮,修遠,吾將上下而求索。”。

所以,不要問怎麽入門,直接上路吧:)