美文网首页
python 处理webservice接口

python 处理webservice接口

作者: 阿登20 | 来源:发表于2021-04-13 01:25 被阅读0次

    一、suds-py3 安装

    关于 suds-py 的安装,安装好 python 之后,直接在命令行使用 pip 进行安装就可以了。

    二、WSDL 文档的介绍

    WebService 的接口是基于 SOAP 协议,每个服务地址都有一个对应 WSDL 文件,WSDL 是一个遵循 WSDL-XML 模式的 XML 文挡,是用来精确描述 Web 服务的文档。一个 WSDL 文档通常包含 8 个重要的元素,即 definitions、types、import、message、portType、operation、binding、service 元素。这些元素嵌套在 definitions 元素中,如下案例所示:

    image.png

    WSDL 文档中我们可以看到这个 webservice 的地址中提供了那些服务(接口),每个服务需要一些什么样的参数等等。和 HTTP 不同的是一个 webservice 地址中提供了多个服务(接口),我们要去使用那个服务(接口),调用对应的方法进行访问即可,关于 WSDL 文档如何去看大家也可以自行扩展学习这边不做过多的扩展,重点给大家介绍在 python 中如何去请求 webservice 接口。

    三、suds 的请求 webservice

    1、案例接口

    为了方便大家学习,我边从网上找了 2 个 webservice 接口的 url 地址来给大家做案例演示:

    2、案列一

    这边我们以 QQ 登录状态查询这个服务地址为例,给大家来讲解;要知道一个 webservice 的地址中有多少个接口,我们可以直接浏览访问 url 地址看 wsdl 的描述文档,我们也可以借助于 soapUI 这个工具,当然我们也可以通过 suds 库创建一个客户端对象,访问该地址去看:

    • 代码如下:
    from suds import client
    
    url = "http://ws.webxml.com.cn/webservices/qqOnlineWebService.asmx?wsdl"
    # 访问url地址返回一个client对象
    web_s = client.Client(url)
    # 打印客户端对象,就可以看到该地址下所有的服务(接口)
    print(web_s)
    
    • 详细信息如下:
    image.png
    • 请求具体的某个接口

      知道接口名和参数之后,我们就可以请求对应的接口了

    from suds import client
    
    url = "http://ws.webxml.com.cn/webservices/qqOnlineWebService.asmx?wsdl"
    # 访问url地址返回一个client对象
    web_s = client.Client(url)
    # 准备参数,请求接口
    res = web_s.service.qqCheckOnline(qqCode='121278987')
    # 获取返回的结果:
    print(res)
    
    

    3、案例二

    上面的 QQ 状态查询是一个比较简单的案例,接口的请求参数和返回参数都比较简单,那么接下来看一个稍微复杂一点的接口,天气预报查询:

    • 第一次请求

      用上一个案例的代码,修改地址直接请求这个时候会出现报错:

      from suds import client
      url = "http://ws.webxml.com.cn/WebServices/WeatherWS.asmx?wsdl"
      # 访问url地址返回一个client对象
      web_s = client.Client(url)
      # 打印客户端对象,就可以看到该地址下所有的服务(接口)
      print(web_s)
      
    • 运行错误:
    image.png

    上述代码报错的原因是因为,suds 在解析返回来的 WSDL 的时候,发现返回的 XML 中的有些类型,不在标准的 XML 架构命名空间中,因此解析的时候报错了,这个时候我们需要加上如下几行代码,导入当前服务的命名空间

    image.png
    • 再次请求
      from suds import client
      url = "http://ws.webxml.com.cn/WebServices/WeatherWS.asmx?wsdl"
      from suds.xsd.doctor import Import, ImportDoctor
      imp=Import('http://www.w3.org/2001/XMLSchema',location='http://www.w3.org/2001/XMLSchema.xsd')
      imp.filter.add('http://WebXml.com.cn/')
      doctor=ImportDoctor(imp)
      
      web_s = client.Client(url,doctor=doctor)
      print(web_s)
      
    • 响应结果
    image.png

    打印连接的客户端可以看到,应该服务地址中有 6 个服务(接口),然后下面还有一些类型的介绍。如果要调用某个方法,就用客户端对象调用对应的方法即可。

    4、自定义类型的请求参数

    • 4.1、基本的字符串类型:

    上面 2 个案例,接口的请求参数都是比较标准的字符串类型,调用的时候直接传入即可,有些服务的参数可能是服务命名空间中自定义的参数类型,那么调用相关服务之前就需要处理参数了

    • 4.2、命名空间内自定义的参数类型

      命名空间内自定义的参数类型,在调用相关方法之前,我们需要去获取参数类型的结构,然后按照结构构造参数

      • 案例

        下面是一个内部 webservice 地址(不对外开放),可以看到该服务下面有三个方法,每个方法中的请求参数都是命名空间内自定义的类型,如果说没有接口文档可以参考,我们如何知道这三个类型的参数应该传入什么呢?

    image.png

    4.3、参数类型的获取

    • 我们以 sendMCode 这个方法为例,这个方法需要一个 SendCodeParams 类型的参数,我们要获取该类型参数的结构,我们可以直接创建一个该类型的对象,打印即可看到该参数的结构

      from suds import client
      # 内部地址
      url = 'http://127.0.0.1:8080/sms-service-war-1.0/ws/smsFacade.ws?wsdl'
      cli = client.Client(url)
      # 创建参数类型
      params = cli.factory.create("ns0:sendCodeParams")
      # 打印参数
      print(params)
      
      运行结果:
    image.png

    运行上述代码,就可以看到 sendCodeParams 这个参数的结构,那么在请求该接口时,按照该格式去组织参数即可(其中有些是非必填参数,这边是看不出来的,需要参考接口文档),好了,关于 webservice 的接口请求就给大家介绍到这里,关于 suds 更多的使用方法,大家可以参考官方文档

    官网的例子

    这个addPerson()方法接受类型为:“Person”的“Person”参数,并具有以下签名:addPerson('Person' person, )其中,参数类型被打印出来,后面跟着它的名称。

    有一个名为“Person”的类型(或类),它与参数的名称不谋而合。或如属.getPercentBodyFat()参数如下弦类型Xs:字符串和整型类型Xs:int.

    因此,要创建一个“Person”对象作为参数传递,我们需要使用“Factory”子命名空间获得Person参数,如下所示:

    #!python
    person = client.factory.create('Person')
    print person
    
    (Person)=
    {
     phone = []
     age = NONE
     name(Name) =
         {
             last = NONE
             first = NONE
         }
    }
    

    如您所见,对象是按照WSDL定义的。电话号码列表是空的,所以我们必须创建一个“phone”对象:

    #!python
    phone = client.factory.create('Phone')
    phone.npa = 202
    phone.nxx = 555
    phone.number = 1212
    

    并且需要设置名称(名称对象)和年龄,我们需要首先创建一个name对象:

    #!python
    name = client.factory.create('Name')
    name.first = 'Elmer'
    name.last = 'Fudd'
    

    现在,让我们设置‘Person’对象的属性:

    #!python
    person.name = name
    person.age = 35
    person.phone = [phone]
    
    

    或:

    #!python
    person.phone.append(phone)
    

    …调用我们的方法addPerson()详情如下:

    #!python
    try:
        person_added = client.service.addPerson(person)
    except WebFault, e:
        print e
    

    就这么简单。

    用户可以不当复杂对象是WSDL/模式中定义的类型的子类(或扩展)时,请使用python‘dict’。换句话说,如果模式将类型定义为“动物”,并且希望传递‘Dog’(假设Dog‘Isa’动物),则可以不用“迪克”来代表狗。在这种情况下,suds需要设置XSI:type=“Dog”但由于python‘dict’没有提供足够的信息来表明它是‘狗’而不是‘动物’,所以不能。最有可能的情况是,服务器将拒绝请求,并指示它无法实例化抽象的“动物”。

    使用Python(Dict)的复杂参数

    就像工厂的例子一样,让我们假设addPerson()方法采用类型为“Person”的“Person”论点。因此,要创建一个“Person”对象作为参数传递,我们需要获得一个Person对象,我们可以通过创建一个简单的python‘dict’来做到这一点。

    #!python
    person = {}
    

    根据WSDL,我们知道Person包含一个电话对象列表,因此我们也需要对它们进行‘dict’s:

    #!python
    phone = {
        'npa':202,
        'nxx':555,
        'number':1212,
    }
    

    …并且需要设置名称(名称对象)和年龄,我们需要首先创建一个name对象:

    #!python
    name = {
        'first':'Elmer',
        'last':'Fudd'
    }
    

    现在,让我们设置‘Person’对象的属性:

    #!python
    person['name'] = name
    person['age'] = 35
    person['phone'] = [phone,]
    …调用我们的方法addPerson()详情如下:
    
    #!python
    try:
       person_added = client.service.addPerson(person)
    except WebFault, e:
      print e
    
    

    webservice封装

    webservice接口 一般只有银行类项目才会有 接触比较少,暂时这样吧

    # !/usr/bin/env python3
    # -*- coding: utf-8 -*-
    """
    ===========================
    @Time : 2021/4/12 23:48
    @Author : 阿登
    @Site : adeng
    @File : webserviceApi.py
    @Software: PyCharm
    ============================
    """
    
    from suds import client
    from suds.xsd.doctor import ImportDoctor, Import
    
    
    class HandleWebservice:
    
        def __init__(self, url):
            self.imp = Import('http://www.w3.org/2001/XMLSchema', location='http://www.w3.org/2001/XMLSchema.xsd')
            self.imp.filter.add('http://WebXml.com.cn/')
            self.doctor = ImportDoctor(self.imp)
            self.client = client.Client(url)
    
        def get_api(self):
            return self.client
    
        def send_res(self, method, *args, **kwargs):
            try:
                cm = eval(f"self.client.{method}")
                res = cm(*args, **kwargs)
                return res
            except Exception as e:
                print(f"\033[0;30;45m{e}\033[0m")
    
        def get_paratype(self, name):
            """
            获取类型参数
            :param name: 自定义类型
            :return:
            """
            return self.client.factory.create(name)
    

    相关文章

      网友评论

          本文标题:python 处理webservice接口

          本文链接:https://www.haomeiwen.com/subject/mrxqlltx.html