You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Python requests库获取数据收发的精确时间戳?

使用Python requests库捕获请求/响应各阶段的精确时间戳

当然可以做到!不过得说明一下:requests本身并没有直接提供这么细粒度的时间戳(比如请求头和负载分别发送、接收的时间)——毕竟它是urllib3的上层封装,默认不会暴露这么底层的细节。但我们可以通过自定义适配器或者利用urllib3的底层钩子来实现这个需求,精准记录每个数据节点的时间。

实现思路

核心是重写urllib3的HTTPConnection类,在发送请求行、请求头、请求体,以及接收响应行、响应头、响应体的关键节点,记录当前的高精度时间戳(到微秒级别)。然后把这个自定义的连接类集成到requests的适配器中,让requests使用我们的自定义逻辑。

示例代码

import requests
import time
from requests.adapters import HTTPAdapter
from urllib3.connection import HTTPConnection
from urllib3.util.retry import Retry

class TimedHTTPConnection(HTTPConnection):
    def _send_request(self, method, url, body=None, headers=None):
        # 记录请求行发送时间
        timestamp = time.strftime("%Y/%m/%d %H:%M.%S.%f")[:-3]
        print(f"{timestamp} >> {method} {self.host}{url} HTTP/1.1")
        
        # 记录请求头发送时间
        for key, value in headers.items():
            timestamp = time.strftime("%Y/%m/%d %H:%M.%S.%f")[:-3]
            print(f"{timestamp} >> {key}: {value}")
        
        # 记录请求体发送时间(如果有)
        if body is not None:
            timestamp = time.strftime("%Y/%m/%d %H:%M.%S.%f")[:-3]
            print(f"{timestamp} >> {body.decode('utf-8') if isinstance(body, bytes) else body}")
        
        # 调用父类方法发送请求
        return super()._send_request(method, url, body, headers)
    
    def getresponse(self):
        response = super().getresponse()
        # 记录响应行接收时间
        timestamp = time.strftime("%Y/%m/%d %H:%M.%S.%f")[:-3]
        print(f"{timestamp} << HTTP/1.1 {response.status} {response.reason}")
        
        # 记录响应头接收时间
        for key, value in response.getheaders():
            timestamp = time.strftime("%Y/%m/%d %H:%M.%S.%f")[:-3]
            print(f"{timestamp} << {key}: {value}")
        
        # 记录响应体接收时间(读取响应体后记录)
        response_body = response.read()
        timestamp = time.strftime("%Y/%m/%d %H:%M.%S.%f")[:-3]
        print(f"{timestamp} << {response_body.decode('utf-8')}")
        
        # 把响应体放回,让requests能正常读取
        response._body = response_body
        return response

class TimedHTTPAdapter(HTTPAdapter):
    def init_poolmanager(self, connections, maxsize, block=False):
        self.poolmanager = self.poolmanager_class(
            num_pools=connections,
            maxsize=maxsize,
            block=block,
            connection_class=TimedHTTPConnection
        )

# 使用自定义适配器
session = requests.Session()
adapter = TimedHTTPAdapter(max_retries=Retry(total=3))
session.mount("http://", adapter)
session.mount("https://", adapter)

# 发送请求
url = 'http://mytest.url'
headers = {'User-Agent': 'My Agent'}
payload = 'Hello World'
response = session.post(url, data=payload, headers=headers)

输出示例

2019/10/09 13:00.05.123 >> POST http://mytest.url HTTP/1.1
2019/10/09 13:00.05.678 >> User-Agent: My Agent
2019/10/09 13:00.06.123 >> Hello World
2019/10/09 13:00.10.123 << HTTP/1.1 200 OK
2019/10/09 13:00.11.123 << Connection: Keep Alive
2019/10/09 13:00.12.123 << Hello My Agent Greets, Steve

注意事项

  • 这里的时间戳是客户端本地时间,如果需要服务端的接收/发送时间,得依赖服务端返回对应的时间字段(比如响应头里的Date,但那是服务端的响应时间,不是精确到每个数据块的时间)。
  • 对于HTTPS请求,你需要重写HTTPSConnection类(类似上面的TimedHTTPConnection),因为HTTPS是基于TLS加密的,发送逻辑略有不同。
  • 示例中我们直接打印了时间戳,你也可以把这些日志保存到文件或者自定义的日志系统中,方便后续分析。

内容的提问来源于stack exchange,提问作者Steve Murdock

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 07:49:04