Skip to main content
 首页 » 编程设计

python之无法使用 SOAPpy 调用 Web 服务方法

2025年05月04日22zhwl

我正在尝试使用 SOAPpy 调用网络服务:

from SOAPpy import SOAPProxy 
 
url = 'http://www.webservicex.net/WeatherForecast.asmx' 
 
server = SOAPProxy(url); 
print server.GetWeatherByPlaceName('Dallas'); 
print server.GetWeatherByZipCode ('33126'); 

服务器调用失败:

Traceback (most recent call last): 
  File "soap_test.py", line 6, in <module> 
    print server.GetWeatherByPlaceName('Dallas'); 
  File "C:\usr\bin\Python26\lib\site-packages\SOAPpy\Client.py", line 451, in __call__ 
    return self.__r_call(*args, **kw) 
  File "C:\usr\bin\Python26\lib\site-packages\SOAPpy\Client.py", line 473, in __r_call 
    self.__hd, self.__ma) 
  File "C:\usr\bin\Python26\lib\site-packages\SOAPpy\Client.py", line 387, in __call 
    raise p 
SOAPpy.Types.faultType: <Fault soap:Client: System.Web.Services.Protocols.SoapException: Server did not recognize the value of HTTP Header SOAPAction: GetWeatherByPlaceName. 
   at System.Web.Services.Protocols.Soap11ServerProtocolHelper.RouteRequest() 
   at System.Web.Services.Protocols.SoapServerProtocol.RouteRequest(SoapServerMessage message) 
   at System.Web.Services.Protocols.SoapServerProtocol.Initialize() 
   at System.Web.Services.Protocols.ServerProtocol.SetContext(Type type, HttpContext context, HttpRequest request, HttpResponse response) 
   at System.Web.Services.Protocols.ServerProtocolFactory.Create(Type type, HttpContext context, HttpRequest request, HttpResponse response, Boolean& abortProcessing): > 

我做错了什么?

请您参考如下方法:

使用 .NET 网络服务时,您可以向调用添加 soap 操作覆盖。像下面这样。确认工作代码。

import SOAPpy 
 
ns = 'http://www.webservicex.net' 
url = '%s/WeatherForecast.asmx' % ns 
 
server = SOAPpy.SOAPProxy( url, namespace=ns ) 
#following is required for .NET 
server.config.buildWithNamespacePrefix = 0 
#adding the soapaction is required for .NET 
print server._sa( '%s/GetWeatherByPlaceName' %ns ).GetWeatherByPlaceName( PlaceName='Dallas' ) 
print server._sa( '%s/GetWeatherByZipCode' %ns ).GetWeatherByZipCode( ZipCode='33126' ) 

有人写了一个class做类似的事情。

上述 .Net 包装器的修改版本:

import SOAPpy 
 
class SOAPProxy( SOAPpy.SOAPProxy ): 
    """Wrapper class for SOAPpy.SOAPProxy 
 
    Designed so it will prepend the namespace to the action in the 
    SOAPAction HTTP headers. 
    """ 
 
    def __call( self, name, args, kw, ns=None, sa=None, hd=None, ma=None ): 
        sa = sa or self.soapaction 
        ns = ns or self.namespace 
        self.config.buildWithNamespacePrefix = 0 
 
        # Only prepend namespace if no soapaction was given. 
        if ns and not sa: 
            if ns.endswith( '/' ): 
                sa = '%s%s' % ( ns , name ) 
            else: 
                sa = '%s/%s' % ( ns , name ) 
 
        #fixup boolean args - .net wants lowercase 
        for arg in kw: 
            if isinstance( kw[ arg ], types.BooleanType ): 
                kw[ arg ] =  SOAPpy.Types.booleanType( kw[ arg ] ) 
 
 
        return SOAPpy.SOAPProxy.__call( self, name, args, kw, ns, sa, hd, ma ) 
 
if __name__ == '__main__': 
    print __doc__