使用zeep调用Cisco CUCM的getProfileSoap接口报命名空间错误如何解决
解决方案
该报错的根本原因是Cisco CUCM WebDialer接口返回的是RPC/Encoded风格的SOAP响应,其中WDDeviceInfo类型所属的urn:WebdialerSoap命名空间未被引入到你加载的主WSDL文件中,导致zeep在校验响应结构时找不到对应的schema定义。可以按以下优先级尝试解决:
方案1:调整zeep配置关闭严格校验(最常用,90%场景可解决)
zeep默认开启严格的schema校验,我们可以通过配置关闭校验,同时开启对SOAP编码格式的支持,适配CUCM的返回格式:
from zeep import Client, Settings # 配置zeep关闭严格校验 settings = Settings( strict=False, # 核心配置:关闭严格schema校验,允许未定义的类型 xml_huge_tree=True, forbid_dtd=False ) # 初始化客户端时传入配置 client = Client('你的WebDialer WSDL地址', settings=settings) # 正常调用接口即可 response = client.service.getProfileSoap(in0={"userID": "foo", "password": "bar"}, in1="just_a_username")
关闭strict模式后,zeep会自动将未定义类型的响应节点转换为可直接读取的字典结构,无需额外处理。
方案2:手动注册缺失的类型定义
如果方案1无法满足类型解析需求,可以手动给zeep注册缺失的WDDeviceInfo类型:
from zeep import xsd # 基于你的响应结构手动定义WDDeviceInfo的字段 WDDeviceInfo = xsd.StructType( [ xsd.Element('deviceName', xsd.String()), xsd.Element('lines', xsd.Array(type=xsd.String())) ], name='WDDeviceInfo' ) # 将定义的类型注册到对应的命名空间下 client.wsdl.types.add_type(WDDeviceInfo, namespace='urn:WebdialerSoap')
注册完成后再调用接口,zeep就可以正常识别解析WDDeviceInfo类型的字段。
方案3:直接解析原始XML响应(极端场景备用)
如果上述方案都不生效,可以跳过zeep的自动解析逻辑,直接获取原始响应XML自行解析:
from lxml import etree # 调用时添加_raw_response参数直接获取HTTP原始响应 response = client.service.getProfileSoap( in0={"userID": "foo", "password": "bar"}, in1="just_a_username", _raw_response=True ) # 用lxml解析XML提取所需字段 root = etree.fromstring(response.content) device_name = root.xpath('//*[local-name()="deviceName"]/text()')[0] line_info = root.xpath('//*[local-name()="lines"]/*[local-name()="item"]/text()')
内容的提问来源于stack exchange,提问作者floatingpurr
相关产品推荐
相关产品推荐

