我用Python寫一個網頁刷屏,使用httplib2的和LXML(是的 - 我知道我可以使用scrapy讓我們搬過去認爲...。)刮板有大約15000頁解析成約400,000件物品。我已經獲得瞭解析項目以便即時(幾乎)運行的代碼,但從服務器下載頁面的部分仍然非常緩慢。我想通過併發來解決這個問題。但是,我無法依賴每一次需要分析的頁面。我已經嘗試過使用單個ThreadPool(比如multiprocessing.pool,但是使用線程完成 - 這應該沒問題,因爲這是一個I/O綁定進程),但我想不出優雅(或工作)的獲取方式所有線程在最後一個索引項的日期大於我們正在處理的項目時停止。現在,我正在研究一個使用ThreadPool的兩個實例的方法 - 一個用於下載每個頁面,另一個用於解析頁面。簡化的代碼示例:Python的 - 多個同時線程池
#! /usr/bin/env python2
import httplib2
from Queue import PriorityQueue
from multiprocessing.pool import ThreadPool
from lxml.html import fromstring
pages = [x for x in range(1000)]
page_queue = PriorityQueue(1000)
url = "http://www.google.com"
def get_page(page):
#Grabs google.com
h = httplib2.Http(".cache")
resp, content = h.request(url, "GET")
tree = fromstring(str(content), base_url=url)
page_queue.put((page, tree))
print page_queue.qsize()
def parse_page():
page_num, page = page_queue.get()
print "Parsing page #" + str(page_num)
#do more stuff with the page here
page_queue.task_done()
if __name__ == "__main__":
collect_pool = ThreadPool()
collect_pool.map_async(get_page, pages)
collect_pool.close()
parse_pool = ThreadPool()
parse_pool.apply_async(parse_page)
parse_pool.close()
parse_pool.join()
collect_pool.join()
page_queue.join()
運行此代碼然而,沒有做什麼,我希望 - 這是火對開的線程池:一個填充隊列,另一個拉動從中解析。它開始收集池,並貫穿它,然後開始parse_pool並貫穿它(我假設,我沒有讓代碼運行足夠長的時間去parse_pool - 重點是collect_pool是所有似乎正在運行)。我相當肯定,我亂七八糟的東西了呼叫的順序加入(),但我不能爲我的生活出他們應該怎樣才能成爲英寸 我的問題基本上是這:我在這裏咆哮着正確的樹嗎?如果是這樣,我到底做錯了什麼?如果我沒有 - 你會有什麼建議是
map_async - 直到它處理完所有工作爲止。 – 2011-05-18 07:12:36
正式地解釋了爲什麼它不起作用,但並不一定回答我的整個問題,歸結爲「這是否是一種瘋狂的方式?」。如果答案是'不',我很接近,我只需要完善我的方法來完成它。如果是的話,我想要一些關於如何「正確地」完成這項工作的指導。 – bbenne10 2011-05-20 00:20:22