2010-04-03 57 views
1

我在python中構建了一個有趣的下載管理器,有時與服務器的連接仍然打開,但服務器不會向我發送數據,所以讀取方法(HTTPResponse )永遠阻擋我。例如,當我從位於我的國家以外的服務器下載時,會出現這種情況,從而限制了其他國家/地區的帶寬。設置超時到http響應在python中讀取方法

如何設置讀取方法的超時時間(例如2分鐘)?

謝謝,尼爾。

+0

相關:[使用urllib2或任何其他http庫讀取超時](http://stackoverflow.com/q/9548869/4279) – jfs 2016-02-08 10:31:01

回答

2

您必須在HTTPConnection初始化期間進行設置。

注意:如果您使用的是舊版本的Python,那麼您可以安裝httplib2;很多人認爲它是httplib的優越替代品,它支持timeout
雖然我從來沒有使用過它,但我只是在報告文檔和博客在說什麼。

+0

+1,但請注意構造函數的timeout參數僅在python 2.6中可用+。 – 2010-04-03 23:40:18

+0

對 - 我已經添加了一些關於httplib2的筆記 – 2010-04-03 23:53:36

+0

我會嘗試它,但我有點懷疑,因爲HTTPResponse類的代碼使用'makefile'方法,該方法無法通過文檔獲取超時:「該套接字必須處於阻止模式(不能有超時)「。 – user164524 2010-04-04 11:49:03

3

如果你被困在一些Python版本< 2.6,一個(不完美,但可以使用)的做法是做

import socket 
socket.setdefaulttimeout(10.0) # or whatever 

在開始使用前httplib。文檔是here,並明確聲明自Python 2.3以來可用的setdefaulttimeout - 從您進行此調用時開始,到您再次調用相同函數爲止的每個套接字都將使用10秒的超時時間。如果您想要保存先前的超時(包括無),可以在設置新的超時之前使用​​,以便稍後恢復(使用另一個setdefaulttimeout)。

只要您需要使用一些使用Python socket s的較舊的高級庫,但不給您一個設置超時的好方法,這些函數和習語非常有用(當然,最好使用更新的更高級別庫,例如在這種情況下帶有2.6或第三方的httplib版本,但這並非總是可行,並且使用默認超時設置播放可能是一種很好的解決方法)。

1

設置默認超時可能會提前終止下載,如果它很大,而不是隻有在它停止接收超時值的數據時才中止。 HTTPlib2可能是要走的路。

-1

5年以後,但希望這將幫助別人......

我被衝倒我的大腦試圖找出了這一點。我的問題是服務器返回損壞的內容,因此回饋的數據比它想象的要少。

我想出了一個似乎正常工作的討厭的解決方案。這裏有雲:

# NOTE I directly disabling blocking is not necessary but it represents 
# an important piece to the problem so I am leaving it here. 
# http_response.fp._sock.socket.setblocking(0) 
http_response.fp._sock.settimeout(read_timeout) 
http_response.read(chunk_size) 

注意該解決方案還適用於蟒蛇請求任何庫,實現了普通的Python插槽(這應該是所有的人?)。你一定要多走幾個層次更深:

resp.raw._fp.fp._sock.socket.setblocking() 
resp.raw._fp.fp._sock.settimeout(read_timeout) 
resp.raw.read(chunk_size) 

在撰寫本文時,我還沒有試過以下,但在理論上它應該工作:

resp = requests.get(some_url, stream=True) 
resp.raw._fp.fp._sock.socket.setblocking() 
resp.raw._fp.fp._sock.settimeout(read_timeout) 
for chunk in resp.iter_content(chunk_size): 
     # do stuff 

說明

我在閱讀此SO問題時偶然發現了這個問題setting a timeout on socket.recv

在一天結束時,任何http請求有一個插座。對於插座位於resp.raw._fp.fp._sock.socket的httplib。 resp.raw._fp.fp._sock是一個socket._fileobj(我真的沒有深入瞭解),我想它是settimeout方法內部將它設置在socket屬性。

+1

如果你想downvote答案,至少給一個人一個理由。 – Realistic 2015-12-12 19:17:50