You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用requests库为HTTP请求设置DNS超时以缩短死链检测时长

问题原因说明

requests 库本身没有暴露 DNS 超时的配置接口,其内置的 timeout 参数仅覆盖 TCP 连接建立和读取响应的阶段。你遇到的5-10秒超时是操作系统底层默认 DNS 解析的超时重试逻辑导致的,该逻辑不受 requests 配置影响。

可选解决方案

方案1:改用异步HTTP库aiohttp(推荐)

适配你提到的协程异步处理思路,aiohttp 原生支持自定义 DNS 超时参数,同时异步并发可以大幅提升批量链接的检测效率,兼容 Windows 10 与 Ubuntu 下的 Python 3.8 环境。

依赖安装

pip install aiohttp

代码示例

import asyncio
from aiohttp import ClientSession, ClientTimeout
from aiohttp.resolver import AsyncResolver

# 配置DNS解析超时1秒,重试次数为0
resolver = AsyncResolver(timeout=1, attempts=1)
# 全局请求总超时2秒,覆盖连接、读取全流程
timeout = ClientTimeout(total=2, connect=1, sock_read=1)

async def check_redirect(sent_url: str):
    async with ClientSession(timeout=timeout, resolver=resolver) as session:
        try:
            async with session.head(sent_url, allow_redirects=False) as resp:
                if resp.status in (301, 302, 303, 307, 308):
                    return resp.headers.get("location", sent_url)
                return sent_url
        except Exception:
            return sent_url

# 批量检测调用示例
async def batch_check(urls: list):
    tasks = [check_redirect(url) for url in urls]
    return await asyncio.gather(*tasks)

if __name__ == "__main__":
    test_urls = ["https://example.com", "https://invalid-test-url-xxx.com"]
    results = asyncio.run(batch_check(test_urls))
    print(results)

方案2:保留requests栈,单独控制DNS解析流程

如果不想修改原有 requests 业务逻辑,可以单独抽离 DNS 解析步骤,用 dnspython 库自行控制解析超时,解析成功后再发起 HTTP 请求。

依赖安装

pip install dnspython requests

代码示例

import requests
import dns.resolver
from urllib.parse import urlparse
from requests.adapters import HTTPAdapter

# 初始化DNS解析器,配置超时1秒
dns_resolver = dns.resolver.Resolver()
dns_resolver.timeout = 1
dns_resolver.lifetime = 1

# 复用requests会话提升性能
http_session = requests.Session()
http_adapter = HTTPAdapter(max_retries=0)
http_session.mount("http://", http_adapter)
http_session.mount("https://", http_adapter)

def check_redirect(sent_url: str):
    try:
        parsed = urlparse(sent_url)
        if not parsed.hostname:
            return sent_url
        # 先做DNS解析,超时直接返回
        dns_resolver.resolve(parsed.hostname, 'A')
        # 解析成功后发起HEAD请求
        response = http_session.head(sent_url, timeout=(1, 1), allow_redirects=False)
        if response.is_redirect:
            return response.headers["location"]
        return sent_url
    except (dns.exception.Timeout, dns.resolver.NXDOMAIN, requests.exceptions.Timeout):
        return sent_url

方案3:修改Ubuntu服务器全局DNS配置

如果无需修改代码,可直接调整部署环境的系统DNS参数,编辑 /etc/resolv.conf 添加如下配置:

options timeout:1 attempts:1

该配置会将系统全局DNS解析超时改为1秒,仅重试1次,即可避免5-10秒的长等待,但该配置对服务器所有程序生效,适合专属部署的服务器使用。


内容的提问来源于stack exchange,提问作者Paul Hübner

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 04:36:02