Jupyter Notebook中requests请求超时挂起问题求助
问题分析与解决方案
可能的原因
- requests的超时逻辑与环境冲突:
requests的timeout=None并非真正完全禁用超时,底层依赖的urllib3在Jupyter的线程环境下,可能出现读取响应时的阻塞问题;而curl作为独立进程,超时处理逻辑更独立、稳健。 - Jupyter主线程阻塞:Jupyter单元格的同步执行会占用主线程,
requests的同步调用长时间阻塞后,可能导致Notebook的I/O事件循环卡住,无法及时接收服务器返回的响应。curl是独立进程,不受Notebook线程限制。 - 服务器分块响应/心跳未被正确处理:长耗时接口可能会发送心跳包或采用分块传输,
requests默认的响应读取方式可能无法识别这些中间信号,导致误认为连接仍在等待;而curl能正确处理这类响应。
诊断方法
- 开启requests调试日志
查看请求各阶段的状态,定位卡在哪个环节:
import requests import logging logging.basicConfig(level=logging.DEBUG) response = requests.get('你的长耗时端点', timeout=None)
- 对比curl与requests的请求头
用curl查看请求头,再用requests模拟相同请求头,排查是否因头信息差异导致问题:
!curl -v 你的长耗时端点
headers = { 'User-Agent': 'curl/7.81.0', # 替换为curl实际的UA 'Accept': '*/*' } response = requests.get('你的长耗时端点', headers=headers, timeout=600)
- 测试分块读取响应
验证是否因一次性等待完整响应体导致阻塞:
response = requests.get('你的长耗时端点', stream=True) for chunk in response.iter_content(chunk_size=1024): if chunk: print("收到数据块")
解决方案
- 使用流式读取响应
避免一次性等待完整响应,逐步接收数据:
response = requests.get('你的长耗时端点', stream=True, timeout=600) full_content = b''.join(response.iter_content(chunk_size=1024))
- 改用异步请求库
避免阻塞Jupyter主线程,推荐使用aiohttp:
import aiohttp import asyncio async def fetch_long_endpoint(): async with aiohttp.ClientSession() as session: async with session.get('你的长耗时端点') as response: return await response.text() await fetch_long_endpoint()
- 升级依赖库
requests依赖的urllib3旧版本可能存在超时处理bug,升级到最新版:
!pip install --upgrade urllib3 requests
内容的提问来源于stack exchange,提问作者baheyen539
相关产品推荐
相关产品推荐

