這個想法很簡單:我需要並行發送多個HTTP請求。在Python 3中發送多個HTTP請求的最佳方式是什麼?
我決定使用requests-futures這個庫,它基本上產生了多個線程。
現在,我有大約200個請求,它仍然很慢(我的筆記本電腦需要大約12秒)。我還使用回調來解析響應json(如庫文檔中所建議的)。另外,有沒有一個經驗法則來確定最佳線程數作爲請求數的函數,是否有?
基本上,我想知道我是否可以進一步加快這些請求。
這個想法很簡單:我需要並行發送多個HTTP請求。在Python 3中發送多個HTTP請求的最佳方式是什麼?
我決定使用requests-futures這個庫,它基本上產生了多個線程。
現在,我有大約200個請求,它仍然很慢(我的筆記本電腦需要大約12秒)。我還使用回調來解析響應json(如庫文檔中所建議的)。另外,有沒有一個經驗法則來確定最佳線程數作爲請求數的函數,是否有?
基本上,我想知道我是否可以進一步加快這些請求。
由於您使用的是python 3.3,我會推薦一個stdlib解決方案,它不會在@ njzk2:concurrent.futures
的鏈接線程中找到。
這是一個更高層次的接口,而不是直接處理threading
或multiprocessing
原語。您將獲得一個Executor
界面來處理池和異步報告。
的文檔有一個例子,基本上是直接適用於您的情況,所以我就放棄它在這裏:
import concurrent.futures
import urllib.request
URLS = #[some list of urls]
# Retrieve a single page and report the url and contents
def load_url(url, timeout):
conn = urllib.request.urlopen(url, timeout=timeout)
return conn.readall()
# We can use a with statement to ensure threads are cleaned up promptly
with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor:
# Start the load operations and mark each future with its URL
future_to_url = {executor.submit(load_url, url, 60): url for url in URLS}
for future in concurrent.futures.as_completed(future_to_url):
url = future_to_url[future]
try:
data = future.result()
# do json processing here
except Exception as exc:
print('%r generated an exception: %s' % (url, exc))
else:
print('%r page is %d bytes' % (url, len(data)))
您可以requests
電話,更換urllib.request
電話,如果你願意的話。我確實傾向於更喜歡requests
,原因很明顯。
這個API有點像這樣:使一堆Future
對象代表你的函數的異步執行。然後,您使用concurrent.futures.as_completed
爲您提供Future
實例的迭代器。它們會在完成時產生它們。
至於你的問題:
此外,有沒有搞清楚的 線程的最佳數量爲請求數的函數經驗法則,有沒有?
經驗法則,沒有。這取決於太多的東西,包括互聯網連接的速度。我會說它並不是真的取決於你的請求數量,更多的是你正在運行的硬件。
幸運的是,調整kwarg並自己測試是很容易的。從5或10個線程開始,以5爲增量遞增。您可能會注意到某些時候性能穩定,然後開始減少,因爲添加額外線程的開銷超過了並行化增加的邊際收益(這是一個字) 。
我想說,在我們的AWS機器上,我已經遇到過有關開放線程的限制,但不在我的筆記本電腦上。這裏概述了這個問題:http://www.alak.cc/2011/11/python-threaderror-cant-start-new.html – BenDundee
@roippi你有沒有看過我的原始文章?它實現了幾乎相同的代碼。 –
@NikolayDerkach不,我沒有,但看着它..呵呵!它基本上將上述內容封裝到一個API調用中,這非常好。這個問題的一個問題是,如果它很慢/行爲不端,你就沒有任何辦法來微調它。例如,當事情出錯時,您可以更輕鬆地測試上述代碼。無論如何,祝你好運:) – roippi
什麼版本的python?你的stdlib選項從2.7到3.3變化很大。 – roippi
我打算建議使用urllib + Threading模塊,但是鏈接到的包本質上是一樣的。至於調整線程的數量,我跑了25左右沒有在我的筆記本電腦上的問題(MacBook Pro,3.2 GHz的處理器,16 GB的RAM)。 – BenDundee
@roippi我正在使用python 3.3 –