使用请求库为 HTTP 请求设置 DNS 超时

Set DNS timeout for HTTP requests using requests library

我有一个函数,用于检查特定 HTTP(S) URL 是否是重定向,如果是 return 新位置(但不是递归)。它使用 requests 库。它看起来像这样:

    try:
        response = http_session.head(sent_url, timeout=(1, 1))
        if response.is_redirect:
            return response.headers["location"]
        return sent_url
    except requests.exceptions.Timeout:
        return sent_url

在这里,我正在检查的 URL 是 sent_url。作为参考,这是我创建会话的方式:

http_session = requests.Session()
http_adapter = requests.adapters.HTTPAdapter(max_retries=0)
http_session.mount("http://", http_adapter)
http_session.mount("https://", http_adapter)

但是,该程序的要求之一是它必须对死的 link 有效。无论我选择什么值,都基于 this, I set a connection timeout (and read timeout for good measures). After playing around with the values, it still takes about 5-10 seconds for the request to fail with this stacktrace。 (可能相关:在浏览器中,它给出 DNS_PROBE_POSSIBLE。)

现在,我的问题是:如果 link 死了,等待 5-10 秒太长了。这个程序需要检查的link很多,我不想死几个link成为这么大的瓶颈,所以我想配置这个DNS查找超时。

我发现几年前的 which seems to be relevant (OP wants to increase the timeout, I want to decrease it) however the solution does not seem applicable. I do not know the IP addresses that these URLs point to. In addition, this feature request 似乎很相关,但对我没有进一步的帮助。

到目前为止,对我来说最好的解决方案似乎只是为每个 link/a 批次的 link 启动一个协程,然后异步吸收超时。

我在 Windows 10,但是此代码将部署在 Ubuntu 服务器上。两者都使用 Python 3.8.

那么,如果我的 HTTP 请求被送死 link,我怎样才能最好地为它提供一个非常低的 DNS 解析超时?

So, how can I best give my HTTP requests a very low DNS resolution timeout in the case that it is being fed a dead link?

分开的东西。

使用 urllib.parse 从 URL 中提取主机名,然后使用 dnspython 解析该名称,超时时间任意。

然后,只有在分辨率正确的情况下,启动 requests 来获取 HTTP 数据。

@blurfus:在requests中,您只能在HTTP 调用中使用超时参数,不能将其附加到会话中。文档中没有明确说明,但代码对此很清楚。

There are many links that this program needs to check,

这其实是一个完全不同的问题,即使所有链接都正常也存在,只是音量的问题。

典型的解决方案有两种:

  • 使用异步库(它们存在于 DNS 和 HTTP 中),你的调用不会阻塞,你稍后会得到数据,所以你可以做其他事情
  • 使用多处理或多线程来并行化事物,并让多个 URL 由您的代码的不同实例同时进行测试。

它们并不完全相互排斥,你可以发现它们各自的优点和缺点,异步代码可能会在以后编写和理解时更加复杂,所以 multiprocessing/multithreading 通常是“快速获胜”(特别是如果您不需要在 processes/threads 之间共享任何东西,否则它很快就会成为一个问题),但是对所有内容的异步处理使得代码可以更好地扩展。