2013-11-20 65 views
6

這個想法很簡單:我需要並行發送多個HTTP請求。在Python 3中發送多個HTTP請求的最佳方式是什麼?

我決定使用requests-futures這個庫,它基本上產生了多個線程。

現在,我有大約200個請求,它仍然很慢(我的筆記本電腦需要大約12秒)。我還使用回調來解析響應json(如庫文檔中所建議的)。另外,有沒有一個經驗法則來確定最佳線程數作爲請求數的函數,是否有?

基本上,我想知道我是否可以進一步加快這些請求。

+0

什麼版本的python?你的stdlib選項從2.7到3.3變化很大。 – roippi

+0

我打算建議使用urllib + Threading模塊,但是鏈接到的包本質上是一樣的。至於調整線程的數量,我跑了25左右沒有在我的筆記本電腦上的問題(MacBook Pro,3.2 GHz的處理器,16 GB的RAM)。 – BenDundee

+0

@roippi我正在使用python 3.3 –

回答

6

由於您使用的是python 3.3,我會推薦一個stdlib解決方案,它不會在@ njzk2:concurrent.futures的鏈接線程中找到。

這是一個更高層次的接口,而不是直接處理threadingmultiprocessing原語。您將獲得一個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爲增量遞增。您可能會注意到某些時候性能穩定,然後開始減少,因爲添加額外線程的開銷超過了並行化增加的邊際收益(這是一個字) 。

+0

我想說,在我們的AWS機器上,我已經遇到過有關開放線程的限制,但不在我的筆記本電腦上。這裏概述了這個問題:http://www.alak.cc/2011/11/python-threaderror-cant-start-new.html – BenDundee

+0

@roippi你有沒有看過我的原始文章?它實現了幾乎相同的代碼。 –

+0

@NikolayDerkach不,我沒有,但看着它..呵呵!它基本上將上述內容封裝到一個API調用中,這非常好。這個問題的一個問題是,如果它很慢/行爲不端,你就沒有任何辦法來微調它。例如,當事情出錯時,您可以更輕鬆地測試上述代碼。無論如何,祝你好運:) – roippi

相關問題