很多老系统还在用 SOAP 协议对外提供服务,比如银行对账接口、政务平台数据上报、ERP 系统集成等。虽然现在 REST 更常见,但真遇到要连一个 WSDL 地址时,还是得手写或调试 SOAP 请求。
最简单的 curl 调用示例
假设你拿到一个 WSDL 地址:https://api.example.com/Service.asmx?wsdl,对应的方法叫 GetUserInfo,需要传入 userId 参数:
curl -X POST \
-H "Content-Type: text/xml; charset=utf-8" \
-H "SOAPAction: \"http://example.com/GetUserInfo\"" \
-d '@request.xml' \
https://api.example.com/Service.asmx其中 request.xml 文件内容如下:
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<GetUserInfo xmlns="http://example.com/">
<userId>12345</userId>
</GetUserInfo>
</soap:Body>
</soap:Envelope>Python requests 调用(不依赖 zeep)
有时候不想装大库,就用原生 requests 发个包:
import requests
url = "https://api.example.com/Service.asmx"
headers = {
"Content-Type": "text/xml; charset=utf-8",
"SOAPAction": "\"http://example.com/GetUserInfo\""
}
body = '''<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<GetUserInfo xmlns="http://example.com/">
<userId>12345</userId>
</GetUserInfo>
</soap:Body>
</soap:Envelope>'''
resp = requests.post(url, headers=headers, data=body)
print(resp.text)注意几个坑
• SOAPAction 头不是所有服务都强制要求,但多数 .NET 服务会校验,值必须和 WSDL 中定义的一致(常是命名空间+方法名);
• XML 中的命名空间(xmlns)不能漏,否则服务端可能返回“未找到操作”;
• 中文参数记得确保整个请求用 UTF-8 编码,XML 声明里也要写 encoding="utf-8";
• 如果返回的是 HTTP 500 但响应体里有详细错误(比如“缺少必需元素”),说明 XML 结构有问题,建议用在线 SOAP 测试工具(如 SoapUI 或 Postman 的 SOAP 模式)先验证。
快速生成请求的小技巧
打开 WSDL 地址(比如 https://api.example.com/Service.asmx?wsdl),浏览器里搜 <message name="GetUserInfo">,就能看到入参结构;再找 <operation name="GetUserInfo">,看它绑定的 soapAction 和命名空间。照着抄,比凭空猜快得多。