python用httplib直接实现soap协议
1.先拿一段php的soap代码来看:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
<?php $client = new SoapClient("http://ws.sb.com/messageservice.asmx?wsdl",Array('trace'=>True)); // 参数转为数组形式传递 $aryPara = array('sender' => 'dantezhu', 'receiver' => 'dantezhu', 'title' => 'OZ评论消息提醒', 'msgInfo' => 'sss', 'messageType'=>0); // 调用远程函数 $ret = $client->SendRTX($aryPara); var_dump($ret); echo $client->__getLastRequest(); ?> |
这段代码是能够正确的发送请求的,通过__getLastRequest打出发送包,如下:
1 2 3 4 5 6 7 8 9 10 11 12 |
<?xml version="1.0" encoding="UTF-8"?> <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://ws.sb.com/common/message"> <SOAP-ENV:Body> <ns1:SendRTX> <ns1:sender>dantezhu</ns1:sender> <ns1:receiver>dantezhu</ns1:receiver> <ns1:title>OZ评论消息提醒</ns1:title> <ns1:msgInfo>sss</ns1:msgInfo> <ns1:messageType>0</ns1:messageType> </ns1:SendRTX> </SOAP-ENV:Body> </SOAP-ENV:Envelope> |
对HTTP请求抓包截图如下:
抓包文件如下:
http://www.vimer.cn/wp-content/uploads/2010/09/1.pcap
2.再来看一下用suds的代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
from suds.client import Client def SendRtx(target,title,content): url = "http://ws.sb.com/messageservice.asmx?wsdl" client = Client(url) client.service.SendRTX( sender = 'dantezhu', receiver = target, title = title, msgInfo = content, messageType = 0 ) senddata = client.last_sent() recvdata = client.last_received() f = file('ss.txt','wb') f.write(str(senddata)) f.close() print senddata print '--------------------------------' print recvdata SendRtx('dantezhu',u'OZ我的天','ss') |
发送包XML如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
<?xml version="1.0" encoding="UTF-8"?> <SOAP-ENV:Envelope xmlns:ns0="http://ws.sb.com/common/message" xmlns:ns1="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"> <SOAP-ENV:Header/> <ns1:Body> <ns0:SendRTX> <ns0:sender>dantezhu</ns0:sender> <ns0:receiver>dantezhu</ns0:receiver> <ns0:title>OZ我的天</ns0:title> <ns0:msgInfo>ss</ns0:msgInfo> <ns0:messageType>0</ns0:messageType> </ns0:SendRTX> </ns1:Body> </SOAP-ENV:Envelope> |
抓包截图如下:
抓包文件如下:
http://www.vimer.cn/wp-content/uploads/2010/09/soapdata
3.仔细对比,发现确实发送的XML是不一样的,但是看了半天也没有发现suds的client有能够手工修改的地方。于是最终决定用urllib或者httplib直接实现。
比较幸运的是找到了这个链接,里面针对不同的webservice提供了不同的方法:
http://users.skynet.be/pascalbotte/rcx-ws-doc/postxmlpython.htm
我们只要模拟一下php的发送的XML,用python来发送就可以啦~
而我们使用的webservice是.net2.0,所以代码如下:
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 27 28 29 30 31 32 |
import urllib2 import sys, httplib def SendRtx(target,title,content): SENDTPL = \ '''<?xml version="1.0" encoding="UTF-8"?> <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://ws.sb.com/common/message"> <SOAP-ENV:Body> <ns1:SendRTX> <ns1:sender>dantezhu</ns1:sender> <ns1:receiver>%s</ns1:receiver> <ns1:title>%s</ns1:title> <ns1:msgInfo>%s</ns1:msgInfo> <ns1:messageType>0</ns1:messageType> </ns1:SendRTX> </SOAP-ENV:Body> </SOAP-ENV:Envelope>''' SoapMessage = SENDTPL % (target,title,content) webservice = httplib.HTTP("ws.sb.com") webservice.putrequest("POST", "/messageservice.asmx") webservice.putheader("Host", "ws.sb.com") webservice.putheader("User-Agent", "Python Post") webservice.putheader("Content-type", "text/xml; charset=\"UTF-8\"") webservice.putheader("Content-length", "%d" % len(SoapMessage)) webservice.putheader("SOAPAction", "\"http://ws.sb.com/common/message/SendRTX\"") webservice.endheaders() webservice.send(SoapMessage) # get the response statuscode, statusmessage, header = webservice.getreply() print "Response: ", statuscode, statusmessage print "headers: ", header print webservice.getfile().read() SendRtx('dantezhu',"素材管理系统","您的单") |
代码文件:
http://www.vimer.cn/wp-content/uploads/2010/09/dir_soap.py
OK,问题解决~果然底层是最靠谱的呀~


浙公网安备 33010602011771号