2013-07-22 46 views
56

在我的劇本,requests.get不會返回:爲什麼不requests.get()返回? requests.get()使用的默認超時是多少?

import requests 

print ("requesting..") 

# This call never returns! 
r = requests.get(
    "http://www.justdial.com", 
    proxies = {'http': '222.255.169.74:8080'}, 
) 

print(r.ok) 

可能是什麼可能的原因(S)?任何補救措施?什麼是get使用的默認超時時間?

+0

這不是足夠的代碼。 'url'和'proxy'從哪裏來? – user2357112

+1

@ user2357112:它有關係嗎?我懷疑。 – Nawaz

+0

它絕對重要。如果您提供您嘗試訪問的網址和您嘗試使用的代理,則可以看到發送類似請求時發生的情況。 – user2357112

回答

78

獲取使用的默認超時是什麼?

默認超時是None,這意味着它會等待(掛起),直到連接關閉。

當您傳入超時值時會發生什麼?

r = requests.get(
    'http://www.justdial.com', 
    proxies={'http': '222.255.169.74:8080'}, 
    timeout=5 
) 
+2

我認爲你是對的。 「無」表示無限(或「等到連接關閉」)。如果我自己超時,它會返回! – Nawaz

+0

快樂吧! –

+1

注意:不適用於HTTPS。 – User

21

requests documentation

你可以告訴請求停止等待與超時參數指定 若干秒後響應:

>>> requests.get('http://github.com', timeout=0.001) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
requests.exceptions.Timeout: HTTPConnectionPool(host='github.com', port=80): Request timed out. (timeout=0.001) 

注:

超時不是整個響應下載的時間限制; 如果服務器未發出響應時間爲 的超時秒數(更精確地說,如果在超時秒內 底層套接字上未收到字節),則會引發異常。

這對我來說很重要,即使timeout爲1秒,requests.get()也需要很長時間才能返回。有解決這個問題的一些方式:

1.使用TimeoutSauce內部類

來源:https://github.com/kennethreitz/requests/issues/1928#issuecomment-35811896

import requests from requests.adapters import TimeoutSauce 

class MyTimeout(TimeoutSauce): 
    def __init__(self, *args, **kwargs): 
     connect = kwargs.get('connect', 5) 
     read = kwargs.get('read', connect) 
     super(MyTimeout, self).__init__(connect=connect, read=read) 

requests.adapters.TimeoutSauce = MyTimeout 

此代碼應該引起我們的設置讀取超時爲等於 連接超時,這是您通過Session.get()調用傳遞的超時值。 (請注意,我並沒有實際測試此代碼,所以 它可能需要一些快速的調試,我只是寫它直入 GitHub的窗口。)

2.使用從kevinburke請求的叉:https://github.com/kevinburke/requests/tree/connect-timeout

從它的文檔:https://github.com/kevinburke/requests/blob/connect-timeout/docs/user/advanced.rst

如果指定超時一個值,就像這樣:

r = requests.get('https://github.com', timeout=5) 

超時值將應用於連接和讀取 超時。指定一個元組,如果你想單獨設置這些值 :

r = requests.get('https://github.com', timeout=(3.05, 27)) 

注:The change has since been merged to the main Requests project

3.使用evenletsignal作爲已經在類似的問題中提到: Timeout for python requests.get entire response

+3

您從未回答缺省值爲 – User

+0

缺省值爲0. –

+0

Quote:您可以告訴請求在超時參數給定秒數後停止等待響應。幾乎所有的生產代碼都應該在幾乎所有的請求中使用這個參數。如果不這樣做可能會導致程序無限期地掛起: 注意 超時不是整個響應下載的時間限制;相反,如果服務器沒有發出超時秒數的響應(更準確地說,如果在超時秒內沒有在底層套接字上接收到字節),則會引發異常。如果沒有明確指定超時,請求不會超時。 – DDay

1

審查了所有的答案,來到了這個問題依然存在的結論。在一些網站上,請求可能會無限掛起,使用多處理似乎過度。這是我的方法(Python 3.5+):

import asyncio 

import aiohttp 


async def get_http(url): 
    async with aiohttp.ClientSession(conn_timeout=1, read_timeout=3) as client: 
     try: 
      async with client.get(url) as response: 
       content = await response.text() 
       return content, response.status 
     except Exception: 
      pass 


loop = asyncio.get_event_loop() 
task = loop.create_task(get_http('http://example.com')) 
loop.run_until_complete(task) 
result = task.result() 
if result is not None: 
    content, status = task.result() 
    if status == 200: 
     print(content) 
+0

這是一個* legal * python代碼嗎?從哪個Python? – Nawaz

+1

@Nawaz Python 3.5+。感謝您的提問,並用Python版本更新了答案。這是合法的Python代碼。請查看aiohttp文檔http://aiohttp.readthedocs.io/en/stable/index.html –

相關問題