使用 Python requests 模块发出 SOAP 请求
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15569330/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Making a SOAP request using Python requests module
提问by masterofdestiny
I used python requests module for REST requests.
我将 python 请求模块用于 REST 请求。
I am trying to make a soap request but I wondered couldn't get an example for this . Here is My soap body and headers.
我正在尝试提出肥皂请求,但我想知道无法为此提供示例。这是我的肥皂正文和标题。
<auth>
<apikey>xcvzxcvcxzv-a0-0035c6fbc04f</apikey>
</auth>
body
身体
<reports>
<report>
<name>Test</name>
</report>
</reports>
And here is wsdl url
这是 wsdl 网址
https://ltn.net/webservices/booking/r1/index.wsdl
Please tell me how can I make a post request here using python. If it is not possible using requestsmodule then what could be the other alternatives?
请告诉我如何使用 python 在这里发出帖子请求。如果无法使用requests模块,那么其他选择是什么?
回答by wRAR
回答by nanonyme
This is largely hypothetical since I'm not aware of anyone actually having implemented it but suds supports making custom implementations of suds.transport.Transport. Once such is suds.transport.http.HttpTransport. So technically by implementing a transport subclass you could create a suds transport that uses requests.
这在很大程度上是假设性的,因为我不知道有人实际实现了它,但是 suds 支持制作 suds.transport.Transport 的自定义实现。曾经是 suds.transport.http.HttpTransport。因此,从技术上讲,通过实现传输子类,您可以创建使用请求的 suds 传输。
http://jortel.fedorapeople.org/suds/doc/suds.transport.http.HttpTransport-class.htmlis what's used by default and it returns http://jortel.fedorapeople.org/suds/doc/suds.transport.Reply-class.htmlso as you can see, it should be fairly simple to wrap requests replies so that suds understands them. Transport request (that should be sent with requests) is documented here http://jortel.fedorapeople.org/suds/doc/suds.transport.Request-class.htmlI might sooner or later implement this if no one beets me to it
http://jortel.fedorapeople.org/suds/doc/suds.transport.http.HttpTransport-class.html是默认使用的,它返回 http://jortel.fedorapeople.org/suds/doc/suds.transport .Reply-class.html如您所见,包装请求回复应该相当简单,以便suds理解它们。传输请求(应与请求一起发送)记录在此处 http://jortel.fedorapeople.org/suds/doc/suds.transport.Request-class.html如果没有人说服我,我可能迟早会实现这一点
Why all this effort? Because suds uses urllib2 internally which is far inferior to python-requests as a HTTP client implementation.
为什么要这么努力?因为 suds 在内部使用 urllib2 作为 HTTP 客户端实现远不如 python-requests。
Yet one more edit: I made a gist available as a starting point https://gist.github.com/nanonyme/6268358. It's MIT code and untested but should work as a starting point for the transport.
还有一个编辑:我提供了一个要点作为起点https://gist.github.com/nanonyme/6268358。它是 MIT 代码且未经测试,但应作为传输的起点。
回答by Komu
I ran into the same problem recently, and unfortunately neither suds nor jurko-suds(a maintained fork of suds) were able to help. This is mainly because suds kept generating wrongly formatted soap envelope (this especially happens if the soap that is supposed to be generated has some content that's supposed to be inside a CDATA) different from what the server was expecting. This was the case even when I tried injecting the soap envelope myself using the __inject option.
我最近遇到了同样的问题,不幸的是,suds 和 jurko-suds(一种维护的 suds 分支)都无法提供帮助。这主要是因为 suds 不断生成格式错误的肥皂信封(如果应该生成的肥皂包含一些应该在 CDATA 内的内容,则尤其会发生这种情况)与服务器预期的不同。即使我尝试使用 __inject 选项自己注入肥皂信封也是如此。
Here's how I solved it using python requests
这是我使用 python 请求解决它的方法
import requests
request = u"""<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:req="http://SOME_URL">
<soapenv:Header>
<user>{0}</user>
<pass>{1}</pass>
</soapenv:Header>
<soapenv:Body>
<req:RequestInfo><![CDATA[<?xml version='1.0' encoding='UTF-8'?><request xmlns='http://SOME_OTHER_URL'>
<Call>
<callID>{2}</callID>
...
</Call>
<Foo>
<Bar>
<Baz>{3}</Baz>
...
</Bar>
<Neytri>
...
</Neytri>
</Foo>
<Title>{4}</Title>
</request>]]></req:RequestInfo>
</soapenv:Body>
</soapenv:Envelope>""".format('Jake_Sully',
'super_secret_pandora_password',
'TYSGW-Wwhw',
'something_cool',
'SalaryPayment',
'Pandora_title',
)
encoded_request = request.encode('utf-8')
headers = {"Host": "http://SOME_URL",
"Content-Type": "application/soap+xml; charset=UTF-8",
"Content-Length": str(len(encoded_request)),
"SOAPAction": "http://SOME_OTHER_URL"}
response = requests.post(url="http://SOME_OTHER_URL",
headers = headers,
data = encoded_request,
verify=False)
print response.content #print response.text
What was really important was to specify the Content-Type in the headers and also the SOAPAction. According to the SOAP 1.1 specifiaction
真正重要的是在标头中指定 Content-Type 以及 SOAPAction。根据SOAP 1.1 规范
The SOAPAction HTTP request header field can be used to indicate the intent of the SOAP HTTP request. The value is a URI identifying the intent. SOAP places no restrictions on the format or specificity of the URI or that it is resolvable. An HTTP client MUST use this header field when issuing a SOAP HTTP Request.
The value of SOAPAction can usually be found in the wsdl file of the API call that you want to make; if absent from the wsdl file then you can use an empty string as the value of that header
SOAPAction 的值通常可以在您要进行的 API 调用的 wsdl 文件中找到;如果 wsdl 文件中不存在,则可以使用空字符串作为该标头的值
Also see:
另见:
回答by nanonyme
In case anyone ends up reading this: suds-based solutions are mostly stagnated but there's a newer library called zeep written on top of requests and lxml. It is a completely separate solution and not a suds fork like these others. I know from personal experience that this is in use in some enterprise environments.
如果有人最终读到这篇文章:基于 suds 的解决方案大多停滞不前,但有一个名为 zeep 的更新库,它写在请求和 lxml 之上。这是一个完全独立的解决方案,而不是像其他人那样的泡沫叉。我从个人经验中知道这在某些企业环境中使用。

