使用requests库向远程UNIX服务器API发送POST请求时遇503代理错误的排查求助
先给你拆解下这个错误的核心意思:
HTTPSConnectionPool(host='xx.xx.xx.xx', port=xx): Max retries exceeded with url: /endpoint_path?api_key=** (Caused by ProxyError('Cannot connect to proxy.', OSError('Tunnel connection failed: 503 Service Unavailable')))
简单说就是你的Python代码在尝试通过代理建立隧道连接目标API时失败了,代理返回了503 Service Unavailable(服务不可用)的状态码,而且重试多次都没能成功。
既然你能用Putty连接服务器,Postman也能成功发请求,那问题大概率出在代码和Postman的请求配置差异上,给你几个具体的排查和解决方向:
1. 核对代理配置的差异
Postman可能是直接连接目标服务器(没走代理),或者你在Postman里手动配置了正确的代理,但Python代码没同步这个设置:
- 如果Postman没走代理:可以在requests请求里强制关闭代理,避免系统自动读取错误的代理配置:
response = requests.post( f'{base_endpoint}/{endpoint_path}?api_key=**', headers=headers, data=json.dumps(data), proxies={'http': None, 'https': None} ) - 如果Postman用了特定代理:把Postman里的代理地址和端口复制出来,在代码里添加代理参数:
proxies = { 'http': 'http://你的代理地址:端口', 'https': 'https://你的代理地址:端口' } response = requests.post( f'{base_endpoint}/{endpoint_path}?api_key=**', headers=headers, data=json.dumps(data), proxies=proxies )
2. 检查系统环境变量的代理设置
requests会自动读取系统的HTTP_PROXY和HTTPS_PROXY环境变量,如果这些变量里的代理地址已经失效或者不正确,就会触发这个错误。你可以先在代码里打印看看当前的代理环境变量:
import os print("HTTP_PROXY:", os.environ.get('HTTP_PROXY')) print("HTTPS_PROXY:", os.environ.get('HTTPS_PROXY'))
如果发现环境变量里的代理不对,可以临时在代码里取消它们的影响,或者直接修改系统环境变量。
3. 对齐Postman和代码的请求头
有时候请求头的差异也会导致代理或服务器拒绝请求,比如Postman会自动添加User-Agent等默认头,而你的代码里可能遗漏了。建议把Postman里的所有请求头(包括Content-Type)完全复制到代码的headers字典里试试。
另外,你当前用data=json.dumps(data)传参的方式,需要确保headers里包含'Content-Type': 'application/json',否则requests默认会把请求头设为application/x-www-form-urlencoded,这可能和Postman的请求格式不一致。更简便的方式是直接用requests的json参数,它会自动序列化数据并设置正确的Content-Type:
response = requests.post( f'{base_endpoint}/{endpoint_path}?api_key=**', headers=headers, json=data )
4. 确认代理的额外验证要求
虽然Postman能成功,但也有可能代理是会话绑定的,或者需要用户名密码认证。你可以检查下Postman的代理设置里有没有配置认证,有的话要在代码的代理参数里加上:
proxies = { 'http': 'http://用户名:密码@代理地址:端口', 'https': 'https://用户名:密码@代理地址:端口' }
备注:内容来源于stack exchange,提问作者Jacob John

