发送请求时会话超时

SMT*_*MTH 9 python session timeout web-scraping python-requests

timeout我正在尝试了解如何在发送请求时在会话中使用。timeout我在下面尝试的方法可以获取网页的内容,但我不确定这是正确的方法,因为我在本文档中找不到 的用法。

import requests

link = "/sf/ask/tagged/web-scraping/"

with requests.Session() as s:
    r = s.get(link,timeout=5)
    print(r.text)
Run Code Online (Sandbox Code Playgroud)

如何在会话中使用超时?

eus*_*iro 21

根据文档-快速入门

您可以使用超时参数告诉请求在给定秒数后停止等待响应。几乎所有生产代码都应该在几乎所有请求中使用此参数。

requests.get('https://github.com/', timeout=0.001)
Run Code Online (Sandbox Code Playgroud)

或者从文档高级使用中您可以设置 2 个值(连接读取超时)

超时值将应用于连接超时和读取 超时。如果您想单独设置值,请指定一个元组:

r = requests.get('https://github.com', timeout=(3.05, 27))
Run Code Online (Sandbox Code Playgroud)

设置会话范围超时

搜索了整个文档,发现不可能在会话范围内设置超时参数。

但是有一个已打开的 GitHub Issue考虑将 Timeout 选项设置为必需或使用默认值),它提供了一种解决方法,您可以像HTTPAdapter这样使用:

import requests
from requests.adapters import HTTPAdapter

class TimeoutHTTPAdapter(HTTPAdapter):
    def __init__(self, *args, **kwargs):
        if "timeout" in kwargs:
            self.timeout = kwargs["timeout"]
            del kwargs["timeout"]
        super().__init__(*args, **kwargs)

    def send(self, request, **kwargs):
        timeout = kwargs.get("timeout")
        if timeout is None and hasattr(self, 'timeout'):
            kwargs["timeout"] = self.timeout
        return super().send(request, **kwargs)
Run Code Online (Sandbox Code Playgroud)

并安装在requests.Session()

s = requests.Session() 
s.mount('http://', TimeoutHTTPAdapter(timeout=5)) # 5 seconds
s.mount('https://', TimeoutHTTPAdapter(timeout=5))
...
r = s.get(link) 
print(r.text)
Run Code Online (Sandbox Code Playgroud)

或者类似地,您可以使用@GordonAitchJay 提出的建议 EnhancedSession

with EnhancedSession(5) as s: # 5 seconds
    r = s.get(link)
    print(r.text)
Run Code Online (Sandbox Code Playgroud)


Gor*_*Jay 3

timeout我不确定这是正确的方法,因为我在本文档中找不到 的用法。

滚动到底部。它肯定在那里。Ctrl您可以通过按+F并输入 来在页面中搜索它timeout

timeout您在代码示例中使用正确。

您实际上可以通过几种不同的方式指定超时,如文档中所述:

如果您为超时指定单个值,如下所示:

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

超时值将应用于 和connect超时read。如果您想单独设置值,请指定一个元组:

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

如果远程服务器非常慢,您可以通过传递 None 作为超时值来告诉 Requests 永远等待响应,然后检索一杯咖啡。

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

尝试使用https://httpstat.us/200?sleep=5000来测试您的代码。

例如,这会引发异常,因为 0.2 秒不足以与服务器建立连接:

import requests

link = "https://httpstat.us/200?sleep=5000"

with requests.Session() as s:
    try:
        r = s.get(link, timeout=(0.2, 10))
        print(r.text)
    except requests.exceptions.Timeout as e:
        print(e)
Run Code Online (Sandbox Code Playgroud)

输出:

HTTPSConnectionPool(host='httpstat.us', port=443): Read timed out. (read timeout=0.2)
Run Code Online (Sandbox Code Playgroud)

这会引发异常,因为服务器在发送响应之前等待 5 秒,这比read设置的 2 秒超时长:

HTTPSConnectionPool(host='httpstat.us', port=443): Read timed out. (read timeout=0.2)
Run Code Online (Sandbox Code Playgroud)

输出:

HTTPSConnectionPool(host='httpstat.us', port=443): Read timed out. (read timeout=2)
Run Code Online (Sandbox Code Playgroud)

您特别提到在会话中使用超时。所以也许您想要一个具有默认超时的会话对象。像这样的东西:

import requests

link = "https://httpstat.us/200?sleep=5000"

with requests.Session() as s:
    try:
        r = s.get(link, timeout=(3.05, 2))
        print(r.text)
    except requests.exceptions.Timeout as e:
        print(e)
Run Code Online (Sandbox Code Playgroud)

输出:

EnhancedSession request
HTTPSConnectionPool(host='httpstat.us', port=443): Read timed out. (read timeout=4)
EnhancedSession request
HTTPSConnectionPool(host='httpstat.us', port=443): Read timed out. (read timeout=1)
EnhancedSession request
<Response [200]>
Run Code Online (Sandbox Code Playgroud)