使用Python requests modu发出SOAP请求

2024-04-20 14:49:33 发布

您现在位置:Python中文网/ 问答频道 /正文

我对REST请求使用python请求模块。

我试图提出一个soap请求,但我想找不到这个例子。 这是我的肥皂盒和头。

<auth>
<apikey>xcvzxcvcxzv-a0-0035c6fbc04f</apikey>
</auth>

身体

<reports>
<report>
<name>Test</name>
</report>
</reports>

这里是wsdl url

https://ltn.net/webservices/booking/r1/index.wsdl

请告诉我如何使用python在这里发出post请求。如果不可能使用requests模块,那么还有什么其他的选择呢?


Tags: 模块nametestreportauthresta0soap
3条回答

要使用SOAP服务器,应该使用专门的库。不幸的是,没有适合Python的SOAP客户机模块,我使用过的最好的模块是suds

这在很大程度上是假设的,因为我不知道有谁真正实现了它,但是suds支持定制suds.transport.transport的实现。这就是suds.transport.http.HttpTransport。所以从技术上讲,通过实现一个传输子类,您可以创建一个使用请求的suds传输。

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 如果没人说服我,我迟早会实施的

为什么这么努力?因为suds在内部使用urllib2,这远不如python请求作为HTTP客户端实现。

还有一个编辑:我提供了一个要点作为起点https://gist.github.com/nanonyme/6268358。它是麻省理工学院的代码,未经测试,但应该作为传输的起点。

我最近遇到了同样的问题,不幸的是,suds和jurko suds(一个维护的suds分支)都无法提供帮助。 这主要是因为sud不断生成格式错误的soap信封(尤其是当应该生成的soap包含一些应该在CDATA中的内容时),这与服务器期望的不同。即使我自己尝试使用“注入”选项注入soap信封时也是这样。

下面是我如何使用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

真正重要的是指定头中的内容类型以及SOAPAction。 根据SOAP 1.1 specifiaction

 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.       

SOAPAction的值通常可以在要进行的API调用的wsdl文件中找到;如果wsdl文件中没有SOAPAction的值,则可以使用空字符串作为该头的值

另见:

  1. http://archive.oreilly.com/pub/post/unraveling_the_mystery_of_soap.html
  2. http://www.prodigyproductionsllc.com/articles/programming/call-a-webservice-using-soap-and-python/

相关问题 更多 >