如何通过使用SOAPpy发出SOAP请求?

狮子座

我正在尝试通过在Python 2.7上使用SOAPpy来调用使用SOAP请求的方法。该方法被调用GetCursOnDate并返回汇率。它带有日期参数。

我正在使用以下代码:

from SOAPpy import SOAPProxy
import datetime

date=datetime.datetime.now()
namespace ="http://web.cbr.ru/"
url = "http://www.cbr.ru/DailyInfoWebServ/DailyInfo.asmx"
server = SOAPProxy(url,namespace)
print (date)
server.GetCursOnDate(date)

但是我得到一个错误:

错误肥皂:客户端:服务器无法识别HTTP标头SOAPAction:GetCursOnDate的值。

为什么会出现此错误?

博格丹

默认情况下,SOAPpy使用方法名称作为HTTPSOAPAction标头的值如果运行以下代码,您将在调试输出中看到该值:

from SOAPpy import SOAPProxy
from datetime import datetime

input = datetime.now()
namespace = "http://web.cbr.ru/"
url = "http://www.cbr.ru/DailyInfoWebServ/DailyInfo.asmx"

proxy = SOAPProxy(url, namespace)
proxy.config.debug = 1
proxy.GetCursOnDate(input)

调试显示此:

*** Outgoing HTTP headers ***************************
POST /DailyInfoWebServ/DailyInfo.asmx HTTP/1.0
Host: www.cbr.ru
User-agent: SOAPpy 0.12.5 (http://pywebsvcs.sf.net)
Content-type: text/xml; charset=UTF-8
Content-length: 406
SOAPAction: "GetCursOnDate"
*****************************************************

但是该服务需要另一个值(http://web.cbr.ru/GetCursOnDate),您可以使用其他参数在代理上设置该以下代码清除了该错误:

from SOAPpy import SOAPProxy
from datetime import datetime

input = datetime.now()
namespace = "http://web.cbr.ru/"
url = "http://www.cbr.ru/DailyInfoWebServ/DailyInfo.asmx"
soapaction = "http://web.cbr.ru/GetCursOnDate"

proxy = SOAPProxy(url, namespace = namespace, soapaction = soapaction)
proxy.config.debug = 1
proxy.GetCursOnDate(input)

调试现在将显示以下内容:

*** Outgoing HTTP headers ***************************
POST /DailyInfoWebServ/DailyInfo.asmx HTTP/1.0
Host: www.cbr.ru
User-agent: SOAPpy 0.12.5 (http://pywebsvcs.sf.net)
Content-type: text/xml; charset=UTF-8
Content-length: 406
SOAPAction: "http://web.cbr.ru/GetCursOnDate"
*****************************************************

但是,尽管该特定故障消失了,但该呼叫无法进行。因为您会带着问题回来,所以我想我会节省一些消息交换的时间,直接写续集。在另一场合提到了对Python的SOAP支持感到失望对于这篇文章,我将在此处添加所有详细信息,作为对自己的参考,并希望对其他用户有所帮助。所以就这样...

该调用将不起作用,因为默认情况下SOAPpy使用有序参数进行调用。它们称为v1等等(有关更多详细信息v2v3请参见MethodParameterNaming.txtSOAPpy下载中文件)。您的SOAP消息将如下所示:

<SOAP-ENV:Body>
    <ns1:GetCursOnDate xmlns:ns1="http://web.cbr.ru/" SOAP-ENC:root="1">
        <v1>
        </v1>
    </ns1:GetCursOnDate>
</SOAP-ENV:Body>

此特定的Web服务需要一个名为的参数On_datenot v1您可以尝试使用命名参数来修复它:

from SOAPpy import SOAPProxy
from datetime import datetime

input = datetime.now()
namespace = "http://web.cbr.ru/"
url = "http://www.cbr.ru/DailyInfoWebServ/DailyInfo.asmx"
soapaction = "http://web.cbr.ru/GetCursOnDate"

proxy = SOAPProxy(url, namespace = namespace, soapaction = soapaction)
proxy.config.debug = 1
proxy.GetCursOnDate(On_date = input)

您的消息现在看起来像这样:

<SOAP-ENV:Body>
    <ns1:GetCursOnDate xmlns:ns1="http://web.cbr.ru/" SOAP-ENC:root="1">
       <On_date>
       </On_date>
    </ns1:GetCursOnDate>
</SOAP-ENV:Body>

我认为缺少日期值,因为代理存在datetime对象问题我实际上并没有检查问题出在哪里,因为此消息还有另一个问题:Web服务期望<ns1:On_date>没有问题<On_date>

这是SOAPpy在名称空间方面存在一些问题的地方。使用原始的SOAPpy源代码,您无法更改名称空间。似乎对于大多数Python的SOAP库,您只能通过调整代码来获得所需的行为,这就是我所做的。SOAPBuilder.py在处理名称空间和标签前缀的某些地方更改了文件。看到原来的文件在这里和一个改变了这里

这些更改使我可以使用SOAPpy类型来更好地控制消息:

from SOAPpy import SOAPProxy
from SOAPpy import Types

namespace = "http://web.cbr.ru/"
url = "http://www.cbr.ru/DailyInfoWebServ/DailyInfo.asmx"
soapaction = "http://web.cbr.ru/GetCursOnDate"
input = Types.dateType(name = (namespace, "On_date"))

proxy = SOAPProxy(url, namespace = namespace, soapaction = soapaction)
proxy.config.debug = 1
proxy.GetCursOnDate(input)

现在,我得到了想要的结果:

<SOAP-ENV:Body>
    <ns1:GetCursOnDate xmlns:ns1="http://web.cbr.ru/" SOAP-ENC:root="1">
      <ns1:On_date xsi:type="xsd:date">2013-11-02Z</ns1:On_date>
    </ns1:GetCursOnDate>
</SOAP-ENV:Body>

服务器根据上述请求返回数据。

但是即使上面的代码也可以改进。请注意,我正在SOAPAction为一个特定操作设置代理上的GetCursOnDate如果要与其他操作一起使用,则需要另一个代理,或者需要修改它。通过使用a,WSDL.Proxy您可以从WSDL自动获得它(它提供了一个SOAPProxy包装程序,包装程序可以SOAPAction从Web服务的WSDL中解析方法名称,名称空间和s)。

但是,即使这是SOAPAction自动处理的,它也不会为该方法选择名称空间。所以我调整了WSDL.py文件。原始版本在这里,更改的文件在这里现在,新的客户端代码如下所示:

from SOAPpy import WSDL
from SOAPpy import Types

# you can download this and use it locally for better performance
wsdl = "http://www.cbr.ru/DailyInfoWebServ/DailyInfo.asmx?wsdl"
namespace = "http://web.cbr.ru/"
input = Types.dateType(name = (namespace, "On_date"))

proxy = WSDL.Proxy(wsdl, namespace = namespace)
proxy.soapproxy.config.debug = 1

proxy.GetCursOnDate(input)

对于上面的示例,我使用了Python 2.6.6,SOAPpy 0.12.5,fpconst 0.7.2和wstools 0.4.3。对于其他人,我认为YMMV取决于您正在调用的版本或特定的Web服务。最后,我还想提及一下,如果您在Google上进行搜索,您会发现大多数人都建议使用SUDS而不是SOAPpy作为SOAP客户端,所以也许也可以看看。祝好运!

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何通过使用SOAPpy获得SOAP主体?

来自分类Dev

如何使用FRENDS发出SOAP请求?

来自分类Dev

如何发出SOAP请求

来自分类Dev

使用PHP发出SOAP请求

来自分类Dev

如何使用AFNetworking或STHTTPRequest发出SOAP Web服务请求?

来自分类Dev

如何使用AFNetworking或STHTTPRequest发出SOAP Web服务请求?

来自分类Dev

如何对wcf服务使用usd Zend \ Soap \ Client \ DotNet发出肥皂请求?

来自分类Dev

如何通过Cookie发出HTTP请求

来自分类Dev

如何通过AFnetworking发出发布请求?

来自分类Dev

如何使用TortoiseGit发出请求请求

来自分类Dev

如何使用请求发出 HTTP HEAD 请求?

来自分类Dev

AFNetworking 2.0,SOAP Web服务:如何发出请求?

来自分类Dev

Django 1.8(在Python 3上)-使用pysimplesoap发出SOAP请求

来自分类Dev

如何通过类比curl请求从JavaScript发出请求

来自分类Dev

如何通过python发送soap请求?

来自分类Dev

使用python向Stackoverflow API发出请求时,如何通过标头传递我的API密钥

来自分类Dev

如何使用Express框架发出AJAX请求?

来自分类Dev

如何使用TcpClient向网站发出请求

来自分类Dev

如何使用grequests发出HTTP POST请求

来自分类Dev

如何使用SwiftyJSON发出发布请求

来自分类Dev

如何使用EGit发出拉动请求?

来自分类Dev

如何使用Plink发出HTTP请求

来自分类Dev

如何使用NetworkStream类发出GET请求?

来自分类Dev

如何使用 RxNET 发出异步 HTTP 请求?

来自分类Dev

如何使用 fetch 发出同步请求?

来自分类Dev

如何使用 HTTPoison 发出异步请求?

来自分类Dev

如何使用 Okio 发出帖子请求?

来自分类Dev

如何使用数组发出 GET 请求

来自分类Dev

如何使用 React 发出 API 请求?

Related 相关文章

热门标签

归档