Python Requests库:如何获取请求响应后连接主机的IP地址
获取Requests请求实际连接的主机IP
针对你遇到的域名对应多IP、需要获取实际连接IP的场景,以下是两种可行的解决方案,适配你当前的Python3.10和Requests代码:
方法1:直接读取底层连接的Socket信息
Requests基于urllib3实现,你可以通过访问响应的底层urllib3连接对象来获取实际连接的IP。response.raw.connection为None是因为stream模式下连接的属性封装方式不同,需要访问私有属性_connection:
# 你的现有代码... response = s.get(url, headers=self.headers, stream=True, timeout=60) # 提取实际连接IP if hasattr(response.raw, '_connection') and response.raw._connection: if hasattr(response.raw._connection, 'sock'): remote_ip, remote_port = response.raw._connection.sock.getpeername() print(f"实际连接的IP地址: {remote_ip}")
方法2:添加请求钩子(适配重试场景)
因为你配置了重试策略,可能存在多次请求重试的情况,使用请求钩子可以确保在每次成功建立连接后捕获IP,结果更可靠:
# 定义钩子函数,捕获连接IP并挂载到response对象 def capture_remote_ip(response, *args, **kwargs): if hasattr(response.raw, '_connection') and response.raw._connection: if hasattr(response.raw._connection, 'sock'): remote_ip, _ = response.raw._connection.sock.getpeername() response.remote_ip = remote_ip # 你的现有代码... s = Session() s.mount('https://', self.adapter) # 给Session添加响应钩子 s.hooks['response'].append(capture_remote_ip) response = s.get(url, headers=self.headers, stream=True, timeout=60) # 直接访问自定义属性获取IP print(f"实际连接的IP地址: {response.remote_ip}")
注意事项
- 建议在处理响应内容前获取IP,避免连接池回收连接后导致属性失效。
- 私有属性
_connection虽非Requests官方公开API,但在当前主流版本中稳定可用,适合生产环境。 - 上述方法适用于HTTP/HTTPS请求,获取的是TLS握手后实际通信的服务器IP,完全匹配你的多IP路由场景。
内容的提问来源于stack exchange,提问作者drajvver
相关产品推荐
相关产品推荐

