如何在服务器A运行Python脚本时让部分请求经服务器B发出
完全可以实现,不需要把整套脚本迁移到服务器B,核心思路是让指定的网络请求通过服务器B代发,脚本的业务逻辑、计算处理全程在A上运行,仅需要出口为B的那部分请求走转发链路即可,改造成本极低。
推荐实现方案(改造成本最低)
最适配你现有requests、urllib.request技术栈的方案是正向代理模式,链路为:A上的指定请求 → 转发到B搭建的代理服务 → B代发请求到目标地址 → 响应原路返回给A上的脚本,全程不需要改动核心业务逻辑。
第一步:在服务器B侧搭建代理入口
你可以根据使用场景选其中一种方式,不需要复杂配置:
- SSH动态端口转发(零额外安装软件,适合测试/安全要求高的场景):不需要在B上装任何服务,只要B开放SSH登录权限,直接在A上执行以下命令即可拉起SOCK5代理隧道:
执行完成后A本地的1080端口会提供SOCK5代理服务,所有走这个代理的请求都会从B的IP出口。这个方案的流量走SSH加密传输,不需要在B上开放额外端口,生产环境可以配置systemd做隧道保活、SSH密钥登录免密。ssh -fN -D 127.0.0.1:1080 B的登录用户@B的IP - 轻量正向代理服务(适合长期稳定运行/多服务共用出口场景):在B上安装Tinyproxy或者Squid这类轻量正向代理软件,配置仅允许A的IP访问代理端口,搭建完成后会得到一个HTTP代理地址(格式为
http://B的IP:代理端口)。
第二步:代码侧仅给需要走B出口的请求配置代理
不需要全局修改所有请求,也不需要改动业务逻辑,只需要给要求走B出口的那部分请求单独加代理参数即可,其余请求默认走A本地出口不受影响:
requests库配置示例:
如果使用SOCK5类型代理,需要先安装依赖:import requests # 代理配置根据你选的代理类型填写,SOCK5代理填socks5h地址,HTTP代理填对应HTTP地址 b_proxy = { "http": "socks5h://127.0.0.1:1080", "https": "socks5h://127.0.0.1:1080" } # 仅这个请求走B出口 resp = requests.get("https://目标访问地址", proxies=b_proxy)pip install "requests[socks]";用socks5h前缀可以让域名解析也走B,避免在A本地泄露解析请求,保证出口全链路都走B。urllib.request库配置示例:import urllib.request # 替换为你实际搭建的代理地址 b_proxy = urllib.request.ProxyHandler({ "http": "http://B的IP:8888", "https": "http://B的IP:8888" }) b_opener = urllib.request.build_opener(b_proxy) # 仅用这个opener发送的请求走B出口 resp = b_opener.open("https://目标访问地址")
其他可选方案(改造成本更高)
如果不想搭代理,也可以根据场景选以下方案,但改造成本和维护复杂度比代理方案高:
- 路由层流量转发:在A上通过iptables配置策略路由,把指定进程、指定目标地址的出向流量直接路由到B做网关转发,这个方案完全不需要改代码,但配置复杂度高,问题排查难度大,灵活度低。
- 接口抽离:把需要走B出口的网络请求逻辑抽成极简的HTTP接口,单独部署在B上,A上的脚本需要对应数据时调用B的接口获取结果,这个方案适合请求逻辑非常固定的场景,但需要拆分部分代码,后续维护要同时维护两边的逻辑。
落地注意事项
- 搭建代理后一定要配置访问控制,仅允许A的IP调用代理服务,同时放通对应防火墙端口,避免代理被公网扫描滥用。
- 上线前可以先给走代理的请求访问公网IP查询地址,确认返回的出口IP是B的IP再正式切流量。
- 如果用SSH隧道方案,一定要配置自动重连机制,避免网络波动导致隧道断开后请求失败。
内容的提问来源于stack exchange,提问作者user1092289
相关产品推荐
相关产品推荐

