我正在尝试使用两种不同的方法在 Python 中获取网页:
requests
和
aiohttp
requests 方法工作正常,但 aiohttp 方法会导致超时。代码如下:
import asyncio
import aiohttp
import requests
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36',
"X-Requested-With": "XMLHttpRequest",
"Cookie": ""
}
url = "an_url"
async def request_requests():
print("Requesting...")
try:
response = requests.get(url, headers=headers, timeout=3)
print(response.text)
except requests.exceptions.ReadTimeout:
print("Timeout REQUESTS")
async def request_aiohttp():
print("Requesting...")
try:
async with aiohttp.ClientSession(headers=headers, timeout=aiohttp.ClientTimeout(total=3)) as session:
async with session.get(url) as response:
print(await response.text())
except asyncio.TimeoutError:
print("Timeout AIOHTTP")
if __name__ == '__main__':
asyncio.run(request_requests())
asyncio.run(request_aiohttp())
当我运行脚本时,
requests
成功检索数据,但
aiohttp
始终超时。这两种方法都设置了 3 秒超时。
有趣的是,此问题发生在我正在使用的特定 URL 上。对于大多数其他 URL,
requests
和
aiohttp
按预期工作。
关于为什么 aiohttp 超时而 requests 没有超时的任何想法?我在这里缺少什么?
问题可能与为
aiohttp
和
requests
设置的超时类型不同有关。 虽然两者都设置为 3 秒,但它们处理底层套接字操作的方式不同。
-
requests
中的timeout
参数是一个 总 超时,涵盖连接建立、发送请求和接收响应的整个过程。 -
aiohttp
中的aiohttp.ClientTimeout(total=3)
也是一个 总 超时,但它涵盖了所有请求步骤。 但是 ,如果服务器在初始连接后响应缓慢(例如,缓慢发送数据块),aiohttp
可能会在达到total
超时之前超时。
出现问题的原因可能是目标服务器建立连接很快,但需要很长时间才能发送完整的响应。
requests
在这种情况下可以正常工作,因为它等待完整的 3 秒以获得任何响应,而
aiohttp
可能会在收到第一个数据块之前就超时。
可以尝试以下方法来解决此问题:
-
增加
aiohttp
超时: 尝试显著增加aiohttp.ClientTimeout(total=...)
,例如 10 秒或更多,以查看问题是否出在服务器响应速度缓慢。 -
使用
aiohttp
中的单独连接和读取超时:aiohttp.ClientTimeout
允许指定单独的连接和读取超时。尝试设置更长的sock_read
超时,该超时控制接收数据的最大时间:
python
async with aiohttp.ClientSession(
headers=headers,
timeout=aiohttp.ClientTimeout(total=10, sock_read=5)
) as session:
# ... 的代码 ...
-
检查代理和 DNS 解析:
确保的
aiohttp
和requests
请求都使用相同的网络配置(例如,代理设置、DNS 服务器)。差异可能会导致一种方法比另一种方法慢得多。
如果在尝试了这些步骤后问题仍然存在,请提供有关目标 URL 的更多上下文信息(如果可能)以及遇到的任何错误消息。这将有助于进一步诊断问题。
标签:python,python-3.x,python-requests,python-asyncio,aiohttp From: 78830098