我正在收集网站列表上的统计数据,为了简单起见,我正在使用请求。这是我的代码:
data=[]
websites=['http://google.com', 'http://bbc.co.uk']
for w in websites:
r= requests.get(w, verify=False)
data.append( (r.url, len(r.content), r.elapsed.total_seconds(), str([(l.status_code, l.url) for l in r.history]), str(r.headers.items()), str(r.cookies.items())) )
现在,我想要请求。10秒后进入超时,这样循环就不会卡住。
这个问题以前也很有趣,但没有一个答案是干净的。
我听说可能不使用请求是一个好主意,但我应该如何得到请求提供的好东西(元组中的那些)。
最大的问题是,如果无法建立连接,请求包会等待太长时间,并阻塞程序的其余部分。
有几种方法来解决这个问题,但当我寻找类似请求的联机程序时,我找不到任何东西。这就是为什么我为请求构建了一个名为reqto(“请求超时”)的包装器,它支持来自请求的所有标准方法的适当超时。
pip install reqto
语法与请求相同
import reqto
response = reqto.get(f'https://pypi.org/pypi/reqto/json',timeout=1)
# Will raise an exception on Timeout
print(response)
此外,还可以设置自定义超时函数
def custom_function(parameter):
print(parameter)
response = reqto.get(f'https://pypi.org/pypi/reqto/json',timeout=5,timeout_function=custom_function,timeout_args="Timeout custom function called")
#Will call timeout_function instead of raising an exception on Timeout
print(response)
重要的注意事项是导入行
import reqto
由于monkey_patch在后台运行,需要比所有其他导入更早地导入请求,线程等。
我相信你可以使用多处理,而不依赖于第三方包:
import multiprocessing
import requests
def call_with_timeout(func, args, kwargs, timeout):
manager = multiprocessing.Manager()
return_dict = manager.dict()
# define a wrapper of `return_dict` to store the result.
def function(return_dict):
return_dict['value'] = func(*args, **kwargs)
p = multiprocessing.Process(target=function, args=(return_dict,))
p.start()
# Force a max. `timeout` or wait for the process to finish
p.join(timeout)
# If thread is still active, it didn't finish: raise TimeoutError
if p.is_alive():
p.terminate()
p.join()
raise TimeoutError
else:
return return_dict['value']
call_with_timeout(requests.get, args=(url,), kwargs={'timeout': 10}, timeout=60)
传递给kwargs的超时是从服务器获取任何响应的超时,参数timeout是获取完整响应的超时。
嗯,我尝试了这个页面上的许多解决方案,仍然面临不稳定,随机挂起,连接性能差。
我现在正在使用Curl,我对它的“max time”功能和全局性能非常满意,即使实现如此糟糕:
content=commands.getoutput('curl -m6 -Ss "http://mywebsite.xyz"')
这里,我定义了一个最大6秒的时间参数,包括连接时间和传输时间。
我相信Curl有一个很好的python绑定,如果你更喜欢坚持python语法:)
最大的问题是,如果无法建立连接,请求包会等待太长时间,并阻塞程序的其余部分。
有几种方法来解决这个问题,但当我寻找类似请求的联机程序时,我找不到任何东西。这就是为什么我为请求构建了一个名为reqto(“请求超时”)的包装器,它支持来自请求的所有标准方法的适当超时。
pip install reqto
语法与请求相同
import reqto
response = reqto.get(f'https://pypi.org/pypi/reqto/json',timeout=1)
# Will raise an exception on Timeout
print(response)
此外,还可以设置自定义超时函数
def custom_function(parameter):
print(parameter)
response = reqto.get(f'https://pypi.org/pypi/reqto/json',timeout=5,timeout_function=custom_function,timeout_args="Timeout custom function called")
#Will call timeout_function instead of raising an exception on Timeout
print(response)
重要的注意事项是导入行
import reqto
由于monkey_patch在后台运行,需要比所有其他导入更早地导入请求,线程等。
我使用请求2.2.1和eventlet不适合我。相反,我可以使用gevent超时代替,因为gevent在我的服务中用于gunicorn。
import gevent
import gevent.monkey
gevent.monkey.patch_all(subprocess=True)
try:
with gevent.Timeout(5):
ret = requests.get(url)
print ret.status_code, ret.content
except gevent.timeout.Timeout as e:
print "timeout: {}".format(e.message)
请注意geevent .timeout. timeout不会被常规异常处理捕获。
所以要么显式地捕获getevent。timeout。timeout
或者传入一个不同的异常,像这样使用:with gevent。Timeout(5, requests.exceptions.Timeout):尽管在引发此异常时没有传递任何消息。