为什么不requests.get()返回? requests.get()使用的默认超时是多less?
在我的脚本中, 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)
可能的原因是什么? 任何补救措施? 什么是使用默认超时?
什么是使用默认超时?
默认的超时时间是None
,这意味着它将等待(挂起),直到连接closures。
当你传入超时值时会发生什么?
r = requests.get( 'http://www.justdial.com', proxies={'http': '222.255.169.74:8080'}, timeout=5 )
从请求文件 :
您可以通过timeout参数告诉请求在给定秒数后停止等待响应:
>>> 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)
注意:
超时不是整个响应下载的时间限制; 相反,如果服务器没有发出超时秒数的响应(更精确地说,如果在超时秒数内没有在底层套接字上接收到字节),则会引发exception。
对于我来说,requests.get()需要很长时间才能返回,即使timeout
是1秒。 有几种方法可以解决这个问题:
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()调用中传递的超时值。 (请注意,我没有真正testing过这个代码,所以可能需要一些快速的debugging,我只是直接写入到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))
注: 该更改已被合并到主Requests项目 。
3.使用类似问题中已经提到的evenlet
或signal
: 超时python requests.get整个响应
审查所有的答案,并得出结论,问题依然存在。 在一些网站上,请求可能无限挂起,使用多处理似乎是矫枉过正的。 这是我的方法(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)