虽说接触过的大部分接口都是以restfullapi的形式返回json数据,但最近有些接口是soap的,如果只是需要一个python的soap客户端的话,suds库是十分不错的一个选择,文档

使用pip安装即可,最基础的使用方法如下,示例来源官网:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
from suds.client import Client
url = 'http://localhost:7080/webservices/WebServiceTestBean?wsdl'
client = Client(url)
print client
Suds - version: 0.3.3 build: (beta) R397-20081121
Service (WebServiceTestBeanService) tns="http://test.server.enterprise.rhq.org/"
Prefixes (1):
ns0 = "http://test.server.enterprise.rhq.org/"
Ports (1):
(Soap)
Methods:
addPerson(Person person, )
echo(xs:string arg0, )
getList(xs:string str, xs:int length, )
getPercentBodyFat(xs:string name, xs:int height, xs:int weight)
getPersonByName(Name name, )
hello()
testExceptions()
testListArg(xs:string[] list, )
testVoid()
updatePerson(AnotherPerson person, name name, )
Types (23):
Person
Name
Phone
AnotherPerson

其中methods就是实现各个功能的方法,types则定义了数据类型:

1
2
result = client.service.getPercentBodyFat('jeff', 68, 170)
print result

比如string,int等简单类型就不多说了,如果想知道Person类型是什么,则可以使用:

1
2
person = client.factory.create('Person')
print person

来查看具体细节:

1
2
3
4
5
6
7
8
9
10
(Person)=
{
phone = []
age = NONE
name(Name) =
{
last = NONE
first = NONE
}
}

同理phone,name都是一种类型,可以使用ractory.create方法进行创建并赋值:

1
2
3
4
5
6
7
8
9
10
phone = client.factory.create('Phone')
phone.npa = 202
phone.nxx = 555
phone.number = 1212
name = client.factory.create('Name')
name.first = 'Elmer'
name.last = 'Fudd'
person.name = name
person.age = 35
person.phone = [phone]

然后就可以调用相关的方法了:client.service.addPerson(person)

有些接口还需要设置soap:Header属性,使用client.set_options(soapheaders=(userid,password))

这里需要注意的就是如果header中有多个节点的话,要使用一个元组添加而不是调用多次set_options函数.

再比较有用的就是如果想看suds构造出的xml信息的话,使用

1
2
3
import logging
logging.basicConfig(level=logging.INFO)
logging.getLogger('suds.client').setLevel(logging.DEBUG)

就可以了,如果还想看更详细的信息,比如请求头,状态码等,还可以使用
logging.getLogger('suds.transport').setLevel(logging.DEBUG)
至于更高级的用法,比如安全认证,xml信息修改注入,多server调用等文档描述的也很详细.

其实soap接口的本质就是向某个url以post方式提交一个xml格式的字符串,当然http头信息也需要相应变化,比如:

1
2
3
4
headers = {"Content-Type": "text/xml; charset=utf-8",
"SOAPAction": "http://www.xxxx.com/service/xxxx",
"Host": "www.xxxx.com"
}

可以使用requests以及urllib2等库发送请求,得到结果使用正则或lxml进行处理.

之前我由于某些原因不想使用suds就是这么做的,这种方法有2点需要注意:

  1. 构造xml字符串的编码问题,以及特殊符号转意:’&’转成’&amp;‘,”<”转成”&lt;
  2. 某些函数必须进行顺序调用(比如必须先调用登录函数才能调用查询函数…),注意把上一个调用结果的cookie带入到下一个调用中,建议使用requests库的session进行自动处理