如何使用 Python 中的 WSDL (SOAP) Web 服务?

我想在 Python 中使用基于 WSDLSOAP 的 Web 服务。我已经查看了 深入巨蟒代码,但 SOAPpy 模块不能在 Python 2.5下工作。

我曾经尝试使用 泡沫,它部分工作,但与某些类型断开(suds。 TypeNotfound: Type not found: ‘ item’)。

我还研究了 客户,但它似乎不支持 WSDL。

我已经看了 ZSI,但它看起来非常复杂。有人有样本代码吗?

WSDL 是 https://ws.pingdom.com/soap/PingdomAPI.wsdl,可以在 PHP5SOAP 客户机上正常工作。

228737 次浏览

现在(从2008年开始) ,所有可用于 Python 的 SOAP 库都很糟糕。我建议尽可能避免使用 SOAP。上一次我们被迫使用来自 Python 的 SOAP Web 服务时,我们用 C # 编写了一个包装器,它一边处理 SOAP,另一边说出 COM。

SOAPpy 不能用于 Python 2.5并不是真的——它能用,尽管它非常简单,而且非常非常基本。如果你想谈论任何更复杂的网络服务,ZSI 是你唯一的朋友。

我发现的真正有用的演示是在 http://www.ebi.ac.uk/Tools/webservices/tutorials/python-这真的帮助我了解如何 ZSI 的工作。

如果你自己卷,我强烈建议看看 http://effbot.org/zone/element-soap.htm

SOAPpy 现在已经过时了,AFAIK,被 ZSL 取代。这是一个没有意义的问题,因为我不能让任何一个在 Python 2.5或 Python 2.6上工作,更不用说编译了

我建议你看看 SUDS

“ Suds 是一个用于消费 Web 服务的轻量级 SOAP Python 客户机。”

我定期寻找一个令人满意的答案,但迄今为止一无所获。我使用 soapUI + 请求 + 手工劳动。

我放弃了,上次我使用 Java 需要来做这件事,上次我使用 Java 被通缉来做这件事,我只是放弃了几次,但这并不是必须的。

在去年成功地使用了 Project Place 的 RESTful API 的请求库之后,我突然想到,也许我可以用类似的方式手动处理我想发送的 SOAP 请求。

事实证明这并不太困难,但是它需要花费很多时间,而且容易出错,特别是当字段的命名不一致时(我今天正在处理的字段有“ jobId”、“ JobId”和“ JobID”)。我使用 soapUI 来加载 WSDL,以便于提取端点等并执行一些手动测试。到目前为止,我很幸运没有受到我正在使用的任何 WSDL 的更改的影响。

我最近偶然发现了同样的问题,以下是我的解决方案大纲:

所需的基本组成代码块

下面是客户端应用程序所需的基本代码块

  1. 会话请求部分: 请求与提供程序的会话
  2. 会话身份验证部分: 向提供程序提供凭据
  3. Client 部分: 创建 Client
  4. SecurityHeader 部分: 将 WS-SecurityHeader 添加到客户端
  5. 使用部分: 根据需要使用可用的操作(或方法)

您需要什么模块?

许多人建议使用类似 urllib2的 Python 模块; 然而,没有一个模块可以工作——至少对于这个特定的项目是这样的。

这是您需要获取的模块列表。 首先,你需要从以下连结下载及安装最新版本的「肥皂水」 :

Pypi.python.org/pypi/suds-jurko/0.4.1.jurko.2

另外,您需要分别从以下链接下载并安装 request 和 suds _ request 模块(免责声明: 我是新来的,所以现在我不能发布多个链接)。

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 Header:

...
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
},
})

有一个相对较新的库,它非常有前途,尽管文档记录仍然很少,但看起来非常干净和简洁: 蟒蛇 Zeep

另请参见 这个答案的示例。

#!/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']))

Zeep 是 Python 的一个不错的 SOAP 库,它匹配您所需要的 http://docs.python-zeep.org