如何用Python/Selenium捕获API响应时间?requests结果与控制台不符求解
解决API响应时间与浏览器控制台不符的问题
问题根源
你用time.time()计算的是从代码执行到拿到响应的总时长,包含Python进程本地调度等额外时间,和浏览器控制台统计的纯网络请求耗时(仅覆盖DNS解析、TCP握手、请求传输、服务器处理、响应传输等阶段)存在差异。另外,浏览器默认启用TCP连接复用、资源缓存,而你的requests请求未配置对应策略,也会导致时间偏差。
解决方案
1. 用requests内置属性获取精准网络耗时
requests的Response对象自带elapsed属性,专门统计从请求发送到响应头部接收的网络耗时,比手动计时更准确:
try: if each_api['method'].upper() == 'GET': response = requests.get(each_api['url'], headers=req_header) # 转换为毫秒便于和浏览器控制台对比 latency = response.elapsed.total_seconds() * 1000 print(f"API耗时: {latency:.2f}ms")
2. 模拟浏览器的连接复用与缓存策略
浏览器会复用TCP连接(HTTP/1.1 Keep-Alive)并缓存静态资源,给requests配置会话可对齐这种行为:
import requests from requests_cache import CachedSession # 创建带缓存和连接复用的会话 session = CachedSession('api_cache', expire_after=3600) # 缓存有效期1小时 try: if each_api['method'].upper() == 'GET': response = session.get(each_api['url'], headers=req_header) latency = response.elapsed.total_seconds() * 1000 print(f"API耗时: {latency:.2f}ms")
如需完全匹配浏览器缓存规则,可手动在请求头中添加Cache-Control等字段。
3. 用Selenium直接捕获浏览器真实耗时
如果需要和控制台时间完全一致,用Selenium监听浏览器网络请求,直接获取浏览器统计的精确数据:
from selenium import webdriver from selenium.webdriver.chrome.options import Options import json # 配置Chrome开启网络日志 chrome_options = Options() chrome_options.set_capability('goog:loggingPrefs', {'performance': 'ALL'}) driver = webdriver.Chrome(options=chrome_options) # 打开目标应用页面 driver.get("你的应用页面URL") # 遍历网络日志,提取API请求耗时 for log in driver.get_log('performance'): msg = json.loads(log['message'])['message'] # 筛选响应完成事件 if msg['method'] == 'Network.responseReceived': req_id = msg['params']['requestId'] req_details = driver.execute_cdp_cmd('Network.getRequestDetails', {'requestId': req_id}) # 计算从请求发起至响应完成的总耗时 total_time = req_details['timing']['responseEnd'] - req_details['timing']['requestStart'] print(f"API {req_details['request']['url']} 耗时: {total_time:.2f}ms") driver.quit()
4. 细分各阶段耗时(可选)
如果需要排查具体环节的耗时差异,用pycurl获取DNS解析、TCP连接等细分阶段的时间:
import pycurl from io import BytesIO buffer = BytesIO() c = pycurl.Curl() c.setopt(c.URL, each_api['url']) # 配置请求头 c.setopt(c.HTTPHEADER, [f"{k}: {v}" for k, v in req_header.items()]) c.setopt(c.WRITEDATA, buffer) # 收集各阶段耗时 stage_times = {} def track_progress(_, __, ___, ____): stage_times['dns解析'] = c.getinfo(c.NAMELOOKUP_TIME) * 1000 stage_times['TCP连接'] = c.getinfo(c.CONNECT_TIME) * 1000 stage_times['请求发送'] = c.getinfo(c.PRETRANSFER_TIME) * 1000 stage_times['首字节响应'] = c.getinfo(c.STARTTRANSFER_TIME) * 1000 stage_times['总耗时'] = c.getinfo(c.TOTAL_TIME) * 1000 c.setopt(c.XFERINFOFUNCTION, track_progress) c.perform() c.close() for stage, time in stage_times.items(): print(f"{stage}: {time:.2f}ms")
内容的提问来源于stack exchange,提问作者T R nethra
相关产品推荐
相关产品推荐

