Python urlopen设置timeout参数后未超时无报错 程序卡住无法终止
问题原因
- urllib内置的
timeout参数仅对连接建立后的请求传输阶段生效,SSL握手、DNS解析、网络代理协商等底层阶段的阻塞无法被该参数限制,会出现超过10秒仍无响应的情况。 - 目标站点配置了反爬校验,你的请求缺少
User-Agent等必要头信息,服务器端会直接挂起连接不返回响应,不会触发超时逻辑。 - urllib的底层网络调用会阻塞系统信号处理,导致Ctrl+C终止指令无法被进程接收,只能强制关闭终端。
解决方法
方案1:替换为requests库(推荐)
requests库的超时机制覆盖全请求周期,信号处理逻辑更完善,可正常响应终止指令,同时支持自定义请求头。
首先安装依赖:pip install requests
示例代码:
import requests headers = { "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36" } # 第一个参数为连接超时,第二个为读取超时,全请求阶段生效 response = requests.get("https://advisor.morganstanley.com/one-hundred-square-group", headers=headers, timeout=(5, 10)) page_html = response.text
方案2:仍使用urllib的适配方案
手动添加请求头,同时添加信号兜底超时逻辑,避免进程永久阻塞:
示例代码:
import signal from urllib.request import Request, urlopen # 定义超时处理函数 def timeout_handler(signum, frame): raise TimeoutError("请求超时") # 注册信号,兜底超时时间设为15秒 signal.signal(signal.SIGALRM, timeout_handler) signal.alarm(15) try: # 手动构造请求,添加User-Agent头 req = Request( url='https://advisor.morganstanley.com/one-hundred-square-group', headers={ "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36" } ) uWF = urlopen(req, timeout=10) page_html = uWF.read() uWF.close() finally: # 关闭告警信号 signal.alarm(0)
内容的提问来源于stack exchange,提问作者Brock
相关产品推荐
相关产品推荐

