
suds 客户端在解析 WSDL 时可能默认选择 HTTP 端口(即使 WSDL URL 为 HTTPS),导致 301 重定向失败;通过显式指定 port 索引(如 port=1)可强制选用 HTTPS 绑定端口,避免协议降级。
suds 客户端在解析 wsdl 时可能默认选择 http 端口(即使 wsdl url 为 https),导致 301 重定向失败;通过显式指定 `port` 索引(如 `port=1`)可强制选用 https 绑定端口,避免协议降级。
在使用 suds(尤其是经典 suds-jurko 或 suds-community 分支)调用基于 HTTPS 的 SOAP Web 服务时,一个常见误区是:仅将 WSDL URL 写成 https://...?wsdl 并不能保证后续 SOAP 请求也走 HTTPS。这是因为 WSDL 文档中通常定义了多个 <port></port> 元素,分别对应不同传输协议(如 http:binding 和 https:binding)。suds 默认会选择列表中的第一个端口(索引 0),而该端口很可能绑定的是 http:// 地址,从而导致请求被服务器返回 301 Moved Permanently —— 更关键的是,suds 不自动处理 301 重定向(尤其在底层 urllib2/http.client 层未启用重定向支持时),最终引发连接失败或认证异常。
✅ 正确做法是:显式指定目标端口索引,确保客户端使用 HTTPS 绑定:
from suds.client import Client
wsdl = "https://path/to/scv?wsdl"
client = Client(wsdl)
# 查看可用端口信息(调试用)
for i, port in enumerate(client.wsdl.services[0].ports):
print(f"Port {i}: {port.name} → {port.binding.name}")
# 假设第二个端口(索引 1)为 'SCVHttpsPort' 或包含 'https' 的 binding
token = client.factory.create("ns1:AuthenticationToken")
token.LoginName = "login"
token.UserId = "userid"
token.Password = "password"
client.set_options(soapheaders=token, port=1) # ← 关键:强制使用 HTTPS 端口
articleno = "articleno"
list_obj = client.factory.create("ns1:ArticlesList")
list_obj.Article.append(articleno)
result = client.service.GetStockLevel(list_obj)? 注意事项:
-
port参数是 0-based 索引,对应client.wsdl.services[0].ports列表位置; - 建议先打印端口名称与绑定信息(如
port.binding.name),确认哪个端口实际使用https://地址(常见命名如*HttpsPort、*SSL、*Secure); - 若 WSDL 动态生成或存在多个 service,需校验
client.wsdl.services长度及目标 service 索引(如services[1]); -
suds不支持自动协议协商,也不内置重定向跟随逻辑,因此依赖 WSDL 描述的准确性 + 显式端口选择是生产环境稳定调用的必要实践; - 替代方案:升级至现代 SOAP 客户端(如
zeep),其默认支持 HTTPS 自动识别、重定向处理及更健壮的 TLS 配置(如证书验证控制)。
? 总结:HTTPS 不是由 WSDL URL 决定的,而是由 WSDL 中 <port></port> 所引用的 <binding></binding> 协议决定。client.set_options(port=N) 是 suds 中最直接、最可靠的协议锁定手段——它绕过了隐式选择逻辑,将控制权交还开发者,是解决“WSDL 是 HTTPS,但请求发到 HTTP”类问题的标准答案。
立即学习“Python免费学习笔记(深入)”;


















