2013-04-01 42 views
1

我想以最快的方式製作數千個POST請求。我如何用Python做到這一點?使用Python發送數千個帖子請求的最快方式是什麼?

到目前爲止,我只是有一個for循環它調用下面的函數多次:

def post(word): 
    data = json.dumps({"word":word}) 
    url = "http://127.0.0.1:8000/updateword" 
    req = urllib2.Request(url, data, {'Content-Type': 'application/octet-stream'}) 
    response=None 
    try: 
     f = urllib2.urlopen(req) 
     response = f.read() 
     f.close() 
    except urllib2.HTTPError, error: 
     k= open('error.html','w') 
     k.write(error.read()) 
     k.close() 
    return response 

有沒有更好的方式來做到這一點?

+0

你有這個時間嗎?它太慢了嗎? – abarnert

+0

是的它已經運行了大約一個小時,甚至沒有完成5%。我主要想知道是否可以同時發出多個請求。 – Abs

+0

嘗試使用谷歌搜索「拒絕服務攻擊」,你應該有很多想法。 – alexis

回答

5

您編寫代碼的方式,在發送下一個請求之前,它會等待一個請求的響應。 (最重要的是,它可能不會重用HTTP連接,這意味着您必須處理每個請求的套接字創建/關閉開銷。然後,根據您測試的結果,實際上很有可能使它成爲更好的測試)。

最簡單的同時創建多個請求的方法是使用線程。而要做到這一點最簡單的方法是用concurrent.futures(或futures from PyPI,如果你使用2.x或3.1):

with concurrent.futures.ThreadPoolExecutor(max_workers=10) as pool: 
    results = pool.map(post, words) 
    concurrent.futures.wait(results) 

如果你願意,你可以寫你自己的線程,並只給每個線程1 /的words 10日,並將它遍歷調用post

def posts(words): 
    for word in words: 
     post(word) 

groupsize = len(words)/10 
t = [threading.Thread(target=posts, args=[words[i*groupsize:(i+1)*groupsize]] 
    for i in range(10)] 
for thread in t: 
    thread.start() 
for thread in t: 
    thread.join() 

無論哪種方式,很明顯,我只是拉那10號憑空(因爲它比最大同時連接大多數的瀏覽器或Web服務的客戶多一點會允許你創建),但你會想做一些性能測試來找到最好的價值。

如果事實證明,最好的價值是巨大的,像500或什麼的,你可能會運行到的,你可以用線程做什麼限制。在這種情況下,你應該考慮使用greenlet。最簡單的方法是使用gevent - 最簡單的方法是重寫代碼以使用grequests而不是urllib2。同時,如果實際的讀取浪費時間,並且實際上並不需要響應,而且它們相當大,並且您不試圖測試服務器發送實際響應的能力,您可能需要一旦你知道你會得到正確的數據就關閉套接字。你可以通過編寫你自己的處理程序來做到這一點urllib2,但這聽起來像很多工作。我認爲在這種情況下,它實際上會更簡單,只需降低到套接字級別即可。首先,記錄每個POST發送的請求,以及在事情發生時返回的預期200行。然後做這樣的事情:

with closing(socket.socket()) as c: 
    c.connect(('127.0.0.1', 8000)) 
    c.send(REQUEST_STRING_FORMAT.format([word])) 
    with c.makefile() as f: 
     response = f.readline() 
     if response != RESPONSE_200_STRING: 
      response += f.read() 
      with open('error.html','w') as k: 
       k.write(response) 
相關問題