前段时间用python3调用Webservice接口,本文记录一下调用方法。
一、组件介绍
通过安装suds库,来实现调用webservice接口官网链接,suds是一个轻量级的基于SOAP的web服务客户端。
安装
.\venv\Scripts\python.exe -m pip install suds-py3
注意: 用pip install suds命令安装 , 安装后运行报错ImportError: No module named client
二、调用代码
1. 简单实例,查询电话归属地
from suds.client import Client
import logging
def test1_get_suds_msg(qryfunc):
try:
client = Client('http://ws.webxml.com.cn/WebServices/MobileCodeWS.asmx?wsdl')
print(client)
result = client.service.__getattr__(qryfunc)('15118888888')
except Exception as e:
logging.error(e)
return []
print(type(result))
return result
执行结果
Suds ( https://github.com/cackharot/suds-py3 ) version: 1.4.5.0 IN build: 20211115
Service ( MobileCodeWS ) tns="http://WebXml.com.cn/"
Prefixes (1)
ns0 = "http://WebXml.com.cn/"
Ports (2):
(MobileCodeWSSoap)
Methods (2):
getDatabaseInfo()
getMobileCodeInfo(xs:string mobileCode, xs:string userID, )
Types (1):
ArrayOfString
(MobileCodeWSSoap12)
Methods (2):
getDatabaseInfo()
getMobileCodeInfo(xs:string mobileCode, xs:string userID, )
Types (1):
ArrayOfString
--------------------------------------------------------------------------------
<class 'suds.sax.text.Text'>
15118888888:广东 广州 广东移动全球通卡
说明
- print(client)可以打印出webservice提供了哪些接口和接口参数
- 需要根据接口返回数据类型,做不同解析
2.项目实战代码(一),接口授权和字段判断
from suds.client import Client
import logging
import json
def to_json(obj):
fields = {}
for field in [x for x in obj.__dict__ if not x.startswith('_') and x != 'metadata']:
data = obj.__getattribute__(field)
try:
if isinstance(data, datetime):
data = data.strftime('%Y-%m-%d %H:%M:%S')
json.dumps(data) # this will fail on non-encodable values, like other classes
fields[field] = data
except TypeError:
fields[field] = None
return fields
def test2_get_suds_msg(qryfunc):
try:
client = Client('http://xxxx.xxxx.com/wsdl',
username='xxxx', password='xxxx')
# print(client)
result = client.service.__getattr__(qryfunc)({}, {'MATNR': '',
'WERKS': '1640'})
except Exception as e:
logging.error(e)
return []
print(type(result))
if str(type(result)) != "<class 'suds.sudsobject.reply'>":
return []
if not hasattr(result, 'MESSAGE'):
logging.error('result返回信息缺少:MESSAGE')
return []
message = result.MESSAGE
if not all([hasattr(message, 'BASIC'), hasattr(message, 'WERKS'), hasattr(message, 'MSGER')]):
logging.error('message返回信息缺少:BASIC, WERKS, MSGER')
return {}
if not hasattr(message.MSGER, 'TYPE'):
logging.error('message.MSGER返回信息缺少:TYPE')
return {}
TYPE = message.MSGER.TYPE
if TYPE != 'S':
return {}
for basic in message.BASIC:
obj = to_json(basic)
print(obj)
return []
说明
- 例子中http://xxxx.xxxx.com/wsdl要换成有效的地址
- Client(‘xxxx’, username=‘xxxx’, password=‘xxxx’)里面的username和password参数用于指定接口访问的用户名和密码
- 对接口数据的字段做验证,增加代码健壮性
- 返回字段
(reply){
BASEINFO =
(DT_BASEINFO){
TRACE_ID = "1FB671CECE431EEC97FCA2A843E4BA03"
SEND_TIME = "20211218173005"
SRC_SYS = "BOKE"
TAR_SYS = "SAP"
SERVICE_NAME = "xxxxxxxxx"
RETRY_TIMES = "0"
}
MESSAGE =
(MESSAGE){
BASIC[] =
(BASIC){
KEY1 = "025203001"
KEY2 = "0603-2500"
},(BASIC){
KEY1 = "600003003"
KEY2 = "0402-600"
},
MSGER =
(MSGER){
TYPE = "S"
}
}
}
3.项目实战代码(二),接口授权和数据处理
from suds.client import Client
import logging
import json
from xml.dom.minidom import parse
import xml.dom.minidom
def test3_get_suds_msg(qryfunc):
try:
client = Client('http://xxxx.xxxx.com/wsdl')
# print(client)
result = client.service.__getattr__(qryfunc)('<Request><Access><Authentication user="xxxx" password="xxxx"/><Organization name="FJJP"/>'
'<Locale language="zh_cn"/></Access><RequestContent><Parameter><Record/></Parameter><Document>'
'<RecordSet id="1"></RecordSet></Document></RequestContent></Request>')
except Exception as e:
logging.error(e)
return []
print(type(result))
results = []
DOMTree = xml.dom.minidom.parseString(result)
collection = DOMTree.documentElement
records = collection.getElementsByTagName("RecordSet")
for r in records:
# print(r)
results.append({})
if r.hasAttribute('id'):
results[-1]['id'] = r.getAttribute('id')
results[-1]['dbname'] = r.getElementsByTagName("Master")[0].getAttribute('name')
data = r.getElementsByTagName("Field")
for da in data:
results[-1][da.getAttribute('name')] = da.getAttribute('value')
print(results[-1])
return results
说明
- 例子中http://xxxx.xxxx.com/wsdl要换成有效的地址
- 接口授权在接口调用参数里面,通过
<Authentication user="xxxx" password="xxxx"/>
输入 - 接口返回数据时文本类型xml格式数据,对返回结果进行了xml解析
- 返回数据字段
<Response>
<Execution>
<Status code="0" description=""/>
</Execution>
<ResponseContent>
<Parameter/>
<Document>
<RecordSet id="1">
<Master name="unit">
<Record>
<Field name="key1" value="PIN"/>
<Field name="key2" value="瓶"/>
</Record>
</Master>
</RecordSet>
<RecordSet id="2">
<Master name="unit">
<Record>
<Field name="key1" value="HE"/>
<Field name="key2" value="盒"/>
</Record>
</Master>
</RecordSet>
</Document>
</ResponseContent>
</Response>