2012-07-16 14 views
0

我需要在Python中執行三步網頁抓取。我有幾個基本頁面,我最初颳了,我需要從這些頁面中選擇一些鏈接並檢索它們指向的頁面,然後再重複一次。訣竅是我想這樣做是異步的,這樣每個請求都會盡快被觸發,並且整個應用程序不會受到單個請求的阻止。我將如何做到這一點?Python中的多步驟併發HTTP請求

直到此時,我一直在做一步與eventlet刮,就像這樣:

urls = ['http://example.com', '...'] 
def scrape_page(url): 
    """Gets the data from the web page.""" 
    body = eventlet.green.urllib2.urlopen(url).read() 
    # Do something with body 
    return data 

pool = eventlet.GreenPool() 
for data in pool.imap(screen_scrape, urls): 
    # Handle the data... 

但是,如果擴展該技術,包括嵌套循環GreenPool.imap,它阻止,直到所有的該組中的請求已完成,這意味着應用程序無法根據需要啓動更多請求。

我知道我可以用Twisted或其他異步服務器來做到這一點,但我不需要這麼龐大的庫,我寧願使用輕量級的東西。不過,我願意接受建議。

+0

我真的建議看看扭曲;這是真的,這個庫很大,但你只需要使用它的http客戶端部分來做到這一點,並且嘗試了兩種類似的任務,高級庫方法就容易得多。 – 2012-07-16 03:44:28

回答

3

這是一個想法......但原諒我,因爲我不知道eventlet。我只能提供一個粗略的概念。

考慮你的「第1步」池生產者。創建一個queue並讓第1步工作人員將他們找到的任何新網址放入隊列中。

創建另一個工作者池。讓這些工人從隊列中拉出來處理它們。如果在他們的過程中他們發現另一個網址,將其放入隊列中。他們將繼續爲後續工作提供食物。

從技術上講,這種方法會使它更容易遞歸超過1,2,3+步。只要他們找到新的網址並將其放入隊列中,工作就會繼續進行。

更好的是,從隊列中的原始URL開始,並創建一個將新網址放入同一隊列的單個池。只需要一個池。

張貼註解

搞笑的是,我張貼了這個答案,去找了eventlet「排隊」相當於是什麼之後,我立刻就發現顯示的正是我剛纔所描述的一個例子:

http://eventlet.net/doc/examples.html#producer-consumer-web-crawler

在那個例子中有producerfetch方法。生產者開始從隊列中拉出url併產生線程到fetchfetch然後將任何新的網址重新放入隊列中,並保持互相饋送。

+0

哦,真棒,我不知道我是如何錯過了這個例子。讓我試試看,我會盡快回復你,但它看起來確實是我所需要的。謝謝! – 2012-07-16 06:29:31

+0

忘了迴應,但它像一個魅力工作!唯一的問題是Windows上的eventlet的綠色線程限制相當低,但這不是什麼大問題。再次感謝! – 2012-09-14 23:31:57

+0

非常歡迎你! – jdi 2012-09-14 23:33:51