Python requests发起HTTP请求时如何指定绑定的源IP地址
多IP网卡下指定Python HTTP请求源IP方案
requests库实现方法
requests没有提供直接指定源IP的公开参数,但可以通过自定义传输适配器改造底层连接逻辑实现,无需替换依赖库。
核心原理是重写urllib3的连接创建方法,在socket发起连接前先绑定指定的本机源IP,可参考以下实现:
import requests import socket from requests.adapters import HTTPAdapter # 配置需要绑定的本机源IP BIND_SOURCE_IP = "10.0.0.25" def custom_create_connection(address, timeout=socket._GLOBAL_DEFAULT_TIMEOUT, source_address=None): host, port = address # 强制覆盖source_address为指定IP,端口随机分配 source_address = (BIND_SOURCE_IP, 0) sock = socket.create_connection((host, port), timeout, source_address) return sock class SourceIPAdapter(HTTPAdapter): def init_poolmanager(self, connections, maxsize, block=False, **pool_kwargs): pool_kwargs["socket_options"] = [] super().init_poolmanager(connections, maxsize, block, **pool_kwargs) # 替换连接池默认的连接创建逻辑 from urllib3 import connection connection.create_connection = custom_create_connection # 调用示例 session = requests.Session() # 给HTTP、HTTPS请求都挂载自定义适配器 session.mount("http://", SourceIPAdapter()) session.mount("https://", SourceIPAdapter()) resp = session.get("http://example.com/foo/bar")
IPv6场景下只需把绑定的IP替换为对应IPv6地址,同时将socket地址族配置为
AF_INET6即可。
原生支持该功能的HTTP库
如果不想自定义适配器,以下库原生支持绑定源IP发起请求:
httpx:接口风格和requests高度兼容,支持HTTP/2,通过local_address参数即可直接指定源IP,使用成本最低:
import httpx with httpx.Client(local_address="10.0.0.25") as client: resp = client.get("http://example.com/foo/bar")
pycurl:基于libcurl封装,通过CURLOPT_INTERFACE配置项可指定绑定的IP或对应网卡,性能表现优异,但API风格和requests差异较大。- Python标准库
urllib.request:无需安装第三方依赖,通过自定义opener重写socket连接逻辑即可实现源IP绑定,但封装步骤相对繁琐。
内容的提问来源于stack exchange,提问作者Chris Hemsworth
相关产品推荐
相关产品推荐

