我正在收集网站列表上的统计数据,为了简单起见,我正在使用请求。这是我的代码:

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秒后进入超时,这样循环就不会卡住。

这个问题以前也很有趣,但没有一个答案是干净的。

我听说可能不使用请求是一个好主意,但我应该如何得到请求提供的好东西(元组中的那些)。


当前回答

Timeout = int(秒)

由于请求>= 2.4.0,您可以使用timeout参数,即:

requests.get('https://duckduckgo.com/', timeout=10)

注意:

Timeout不是整个响应下载的时间限制;相反, 如果服务器没有发出响应,则会引发异常 超时秒(更准确地说,如果在 底层套接字超时秒)。如果未指定超时时间 显然,请求不会超时。

其他回答

Timeout = int(秒)

由于请求>= 2.4.0,您可以使用timeout参数,即:

requests.get('https://duckduckgo.com/', timeout=10)

注意:

Timeout不是整个响应下载的时间限制;相反, 如果服务器没有发出响应,则会引发异常 超时秒(更准确地说,如果在 底层套接字超时秒)。如果未指定超时时间 显然,请求不会超时。

如果你使用选项stream=True,你可以这样做:

r = requests.get(
    'http://url_to_large_file',
    timeout=1,  # relevant only for underlying socket
    stream=True)

with open('/tmp/out_file.txt'), 'wb') as f:
    start_time = time.time()
    for chunk in r.iter_content(chunk_size=1024):
        if chunk:  # filter out keep-alive new chunks
            f.write(chunk)
        if time.time() - start_time > 8:
            raise Exception('Request took longer than 8s')

该解决方案不需要信号或多处理。

嗯,我尝试了这个页面上的许多解决方案,仍然面临不稳定,随机挂起,连接性能差。

我现在正在使用Curl,我对它的“max time”功能和全局性能非常满意,即使实现如此糟糕:

content=commands.getoutput('curl -m6 -Ss "http://mywebsite.xyz"')

这里,我定义了一个最大6秒的时间参数,包括连接时间和传输时间。

我相信Curl有一个很好的python绑定,如果你更喜欢坚持python语法:)

尝试这个请求的超时和错误处理:

import requests
try: 
    url = "http://google.com"
    r = requests.get(url, timeout=10)
except requests.exceptions.Timeout as e: 
    print e

我使用请求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):尽管在引发此异常时没有传递任何消息。