问题:如何在Python中使用WSDL(SOAP)Web服务?
我想在Python中使用基于WSDL SOAP的Web服务。我看过Dive Into Python代码,但是SOAPpy模块在Python 2.5下不起作用。
我已经尝试使用肥皂水(:类型未找到:“项目” suds.TypeNotFound),这部分工作,但打破了某些类型。
我也查看了Client,但这似乎不支持WSDL。
我看过ZSI,但它看起来非常复杂。有人有任何示例代码吗?
WSDL是https://ws.pingdom.com/soap/PingdomAPI.wsdl,可与PHP 5 SOAP客户端配合使用。
回答 0
我建议您看看SUDS
“ Suds是用于使用Web服务的轻量级SOAP python客户端。”
回答 1
有一个相对较新的库,它很有前途,尽管文档仍然很少,但看起来很干净并且是pythonic的:python zeep。
另请参见此答案的示例。
回答 2
我最近偶然发现了同样的问题。这是我的解决方案的摘要:
所需的基本组成代码块
以下是客户端应用程序所需的基本代码块
- 会话请求部分:请求与提供者进行会话
- 会话认证部分:向提供者提供凭据
- 客户端部分:创建客户端
- 安全标题部分:将WS-Security标头添加到客户端
- 消耗部分:根据需要消耗可用的操作(或方法)
您需要什么模块?
许多建议使用Python模块,例如urllib2;但是,这些模块都不起作用-至少对于该特定项目不起作用。
因此,这是您需要获取的模块列表。首先,您需要从以下链接下载并安装最新版本的suds:
pypi.python.org/pypi/suds-jurko/0.4.1.jurko.2
此外,您需要分别从以下链接下载和安装请求和suds_requests模块(免责声明:我是新来此发布者,因此我现在不能发布多个链接)。
pypi.python.org/pypi/requests
pypi.python.org/pypi/suds_requests/0.1
一旦成功下载并安装了这些模块,就可以了。
代码
按照前面概述的步骤,代码如下所示:导入:
import logging
from suds.client import Client
from suds.wsse import *
from datetime import timedelta,date,datetime,tzinfo
import requests
from requests.auth import HTTPBasicAuth
import suds_requests
会话请求和身份验证:
username=input('Username:')
password=input('password:')
session = requests.session()
session.auth=(username, password)
创建客户端:
client = Client(WSDL_URL, faults=False, cachingpolicy=1, location=WSDL_URL, transport=suds_requests.RequestsTransport(session))
添加WS-Security标头:
...
addSecurityHeader(client,username,password)
....
def addSecurityHeader(client,username,password):
security=Security()
userNameToken=UsernameToken(username,password)
timeStampToken=Timestamp(validity=600)
security.tokens.append(userNameToken)
security.tokens.append(timeStampToken)
client.set_options(wsse=security)
请注意,此方法将创建图1所示的安全标头。因此,您的实现可能会有所不同,具体取决于所使用服务的所有者提供的正确安全标头格式。
消耗相关的方法(或操作):
result=client.service.methodName(Inputs)
正在记录:
在这种实现中的最佳实践之一是记录日志,以查看通信是如何执行的。万一有问题,它使调试变得容易。以下代码进行基本日志记录。但是,除了代码中描述的内容外,您还可以记录通信的许多方面。
logging.basicConfig(level=logging.INFO)
logging.getLogger('suds.client').setLevel(logging.DEBUG)
logging.getLogger('suds.transport').setLevel(logging.DEBUG)
结果:
这是我的情况的结果。请注意,服务器返回了HTTP200。这是HTTP请求响应的标准成功代码。
(200, (collectionNodeLmp){
timestamp = 2014-12-03 00:00:00-05:00
nodeLmp[] =
(nodeLmp){
pnodeId = 35010357
name = "YADKIN"
mccValue = -0.19
mlcValue = -0.13
price = 36.46
type = "500 KV"
timestamp = 2014-12-03 01:00:00-05:00
errorCodeId = 0
},
(nodeLmp){
pnodeId = 33138769
name = "ZION 1"
mccValue = -0.18
mlcValue = -1.86
price = 34.75
type = "Aggregate"
timestamp = 2014-12-03 01:00:00-05:00
errorCodeId = 0
},
})
回答 3
现在(截止到2008年),所有可用于Python的SOAP库都非常烂。我建议尽可能避免使用SOAP。上次我们被迫使用Python中的SOAP Web服务时,我们用C#编写了一个包装器,该包装器一方面处理SOAP,另一方面则使COM退出。
回答 4
Zeep是一个适合Python的不错的SOAP库,它可以满足您的要求:http : //docs.python-zeep.org
回答 5
我定期寻找一个令人满意的答案,但是到目前为止还没有运气。我使用soapUI +请求+体力劳动。
我上次需要这样做时放弃并使用了Java ,而上次我想这样做时仅放弃了几次,但这并不是必需的。
去年在Project Place的RESTful API中成功使用了请求库之后,我想到也许我可以以类似的方式手动滚动要发送的SOAP请求。
事实证明,这并不是很困难,但是这很耗时且容易出错,尤其是如果字段名称不一致(我当前正在使用的字段具有“ jobId”,“ JobId”和“ JobID”。我使用soapUI加载) WSDL,以便更轻松地提取端点等并执行一些手动测试。到目前为止,我很幸运没有受到我正在使用的任何WSDL更改的影响。
回答 6
并非如此,SOAPpy不适用于Python 2.5-它可以工作,尽管它非常简单,而且确实非常基础。如果您想与任何更复杂的Web服务进行对话,则ZSI是您唯一的朋友。
我发现的真正有用的演示位于http://www.ebi.ac.uk/Tools/webservices/tutorials/python-这确实帮助我了解了ZSI的工作原理。
回答 7
如果您要自己动手,则强烈建议您访问http://effbot.org/zone/element-soap.htm。
回答 8
SOAPpy现在已过时,已经被ZSL取代了AFAIK。这是有争议的,因为在Python 2.5或Python 2.6上我都无法工作,更不用说编译了。
回答 9
#!/usr/bin/python
# -*- coding: utf-8 -*-
# consume_wsdl_soap_ws_pss.py
import logging.config
from pysimplesoap.client import SoapClient
logging.config.dictConfig({
'version': 1,
'formatters': {
'verbose': {
'format': '%(name)s: %(message)s'
}
},
'handlers': {
'console': {
'level': 'DEBUG',
'class': 'logging.StreamHandler',
'formatter': 'verbose',
},
},
'loggers': {
'pysimplesoap.helpers': {
'level': 'DEBUG',
'propagate': True,
'handlers': ['console'],
},
}
})
WSDL_URL = 'http://www.webservicex.net/stockquote.asmx?WSDL'
client = SoapClient(wsdl=WSDL_URL, ns="web", trace=True)
client['AuthHeaderElement'] = {'username': 'someone', 'password': 'nottelling'}
#Discover operations
list_of_services = [service for service in client.services]
print(list_of_services)
#Discover params
method = client.services['StockQuote']
response = client.GetQuote(symbol='GOOG')
print('GetQuote: {}'.format(response['GetQuoteResult']))