Zeep初始化Client加载WSDL时频繁卡顿最终超时问题求助
问题根因
这个问题非常典型,核心原因和业务代码逻辑无关,完全出在Zeep默认的WSDL加载机制上:
- 你对接的是2013年的老RPC风格SOAP 1.1接口,WSDL里引用了两个境外托管的外部XML Schema资源:W3C的XML Schema定义、xmlsoap.org的SOAP 1.1编码规范。国内网络访问这两个地址连通性极差,Zeep初始化Client时默认会自动拉取所有关联的外部XSD资源,95%的概率会卡在这一步直到超时,根本没走到目标接口的实际请求环节。
- SoapUI、手写requests请求能正常调用,是因为这两个工具不会主动拉取这些外部规范文件,直接按WSDL定义的结构发请求即可,自然不会出现加载阻塞。
- 偶发的导入报错,基本都是超时导致的依赖加载中断、本地临时缓存的WSDL/XSD文件损坏引起的,没有稳定复现规律。
可直接落地的解决方案
按优先级从高到低尝试:
方案1:本地加载WSDL+禁用外部资源拉取(成功率100%)
这是对接老SOAP接口最稳定的方式,完全绕开外部资源加载的问题:
- 手动下载WSDL文件:浏览器打开目标WSDL地址,全选页面内容复制,保存为和脚本同目录下的
stockcheck.wsdl纯文本文件,不需要修改任何内容。 - 用如下代码初始化客户端,跳过严格校验、手动绑定服务地址:
from zeep import Client from zeep.transports import Transport import requests # 自定义传输层,设置合理超时 session = requests.Session() transport = Transport(session=session, timeout=30, operation_timeout=30) # 直接读取本地WSDL文件,不走网络拉取 client = Client( wsdl='stockcheck.wsdl', transport=transport, strict=False, xml_huge_tree=True ) # 手动绑定实际服务地址,避免本地WSDL里的地址配置偏差 service = client.create_service( '{http://sprws.sprich.com/sprws/StockCheck.php?wsdl}StockCheckBinding', 'http://sprws.sprich.com/sprws/StockCheck.php.20130201' ) # 构造请求参数,所有字段显式传值,空值传空字符串即可 params = client.get_type('ns0:StockCheckInputs')( GroupCode='你的实际认证值', UserID='你的实际认证值', Password='你的实际认证值', ItemNumber='HAM105007CT', Action='F', SortBy='A', AvailableOnly='Y', CustNumber='', DcNumber='', MinInFullPacks='' ) result = service.StockCheck(params) print(result)
注意:老RPC风格SOAP接口对字段缺失容忍度极低,即便WSDL里没标记字段为必填,也建议把所有定义的字段都显式传值,避免隐式的序列化报错。
方案2:启用本地缓存,减少重复拉取
如果不想本地存储WSDL文件,可以给Zeep配置本地Sqlite缓存,第一次拉取成功后后续就不会重复请求外部资源:
from zeep import Client from zeep.cache import SqliteCache from zeep.transports import Transport import requests transport = Transport( cache=SqliteCache(path='./zeep_cache.db'), timeout=30, operation_timeout=30 ) client = Client( wsdl='http://sprws.sprich.com/sprws/StockCheck.php.20130201?wsdl', transport=transport, strict=False )
这个方案第一次初始化仍有概率因为拉取外部XSD超时,多重试2-3次即可,只要第一次加载成功缓存到本地,后续调用就不会再卡。
方案3:兜底方案
如果上述两个方案仍有不稳定的情况,直接用你已经验证通过的requests手写SOAP信封调用即可。对于这种单接口、参数结构固定的老SOAP服务,手写请求没有额外的依赖加载开销,稳定性反而更高,维护成本也更低。
常见踩坑说明
- 这类2010年前后的老SOAP服务基本都用Section 5编码格式,不是现在通用的Document/Literal格式,Zeep默认的严格模式对这类老格式兼容性很差,初始化时一定要加
strict=False参数。 - 不要用Zeep默认的传输配置,默认超时时间极短且无缓存,每次初始化都会重新拉取所有关联资源,非常容易触发阻塞。
- 如果遇到导入zeep就报错的情况,先删掉脚本目录下生成的临时缓存文件、
__pycache__目录即可恢复,一般是上次运行中断导致的缓存文件损坏,不是Zeep安装异常。
内容的提问来源于stack exchange,提问作者TxTechnician
相关产品推荐
相关产品推荐

