Dan*_*Dan 3 python python-3.x python-asyncio aiohttp
是否可以获取使用 aiohttp 发出的每个请求的响应时间和响应大小?
文档似乎在任何地方都没有这些属性。
谢谢
len(response.text())
将返回解压缩响应的大小。如果您想要原始压缩响应的大小,则需要auto_decompress=False
在创建aiohttp.ClientSession
. 之后,您可以使用len(await response.read())
. 但它会变得不response.text()
可用,因为它需要未压缩的响应。要使其再次可用,您必须手动解压缩它:
import time
import zlib
import brotli
async with aiohttp.ClientSession(auto_decompress=False) as session:
start = time.monotonic()
response = await session.get(url='www.test.com')
response_time = time.monotonic() - start
response_size = len(await response.read())
encoding = response.headers['Content-Encoding']
if encoding == 'gzip':
response._body = zlib.decompress(response._body, 16 + zlib.MAX_WBITS)
elif encoding == 'deflate':
response._body = zlib.decompress(response._body, -zlib.MAX_WBITS)
elif encoding == 'br':
response._body == brotli.decompress(response._body)
response_text = await response.text()
Run Code Online (Sandbox Code Playgroud)
关于time.time()
来自pymotw.com:
由于
time.time()
查看系统时钟,并且系统时钟可以由用户或系统服务更改以在多台计算机之间同步时钟,因此time.time()
重复调用可能会产生向前和向后的值。在尝试测量持续时间或以其他方式使用这些时间进行计算时,这可能会导致意外行为。使用 避免这些情况time.monotonic()
,它总是返回前进的值。
aiohttp 文档建议使用loop.time()(这也是单调的):
async def on_request_start(session, trace_config_ctx, params):
trace_config_ctx.start = asyncio.get_event_loop().time()
async def on_request_end(session, trace_config_ctx, params):
elapsed = asyncio.get_event_loop().time() - trace_config_ctx.start
print("Request took {}".format(elapsed))
trace_config = aiohttp.TraceConfig()
trace_config.on_request_start.append(on_request_start)
trace_config.on_request_end.append(on_request_end)
async with aiohttp.ClientSession(trace_configs=[trace_config]) as client:
client.get('http://example.com/some/redirect/')
Run Code Online (Sandbox Code Playgroud)
一种可能性可能是:
一个小的自包含示例可能如下所示:
import time
import asyncio
from aiohttp import ClientSession
async def fetch(session, url):
start = time.time()
async with session.get(url) as response:
result = await response.text()
end = time.time()
print(url, ": ", end - start, "response length:", len(result))
return result
async def crawl(urls: set):
async with ClientSession() as session:
tasks = []
for url in urls:
tasks.append(
fetch(session, url)
)
await asyncio.gather(*tasks)
if __name__ == "__main__":
urlSet = {"https://www.software7.biz/tst/number.php",
"https://www.software7.biz/tst/number1.php",
"https://www.software7.biz"}
asyncio.run(crawl(urlSet))
Run Code Online (Sandbox Code Playgroud)
测试
两个端点 number.php 和 number1.php 在服务器端有 3 个 1 秒的延迟,每个都返回一个两位数。
调试控制台中的输出如下所示:
https://www.software7.biz : 0.16438698768615723 response length: 4431
https://www.software7.biz/tst/number1.php : 1.249755859375 response length: 2
https://www.software7.biz/tst/number.php : 3.214473009109497 response length: 2
Run Code Online (Sandbox Code Playgroud)