【问题标题】:SoapAPI call to python dict process produces empty file对 python dict 进程的 Soap API 调用产生空文件
【发布时间】:2020-07-09 18:00:22
【问题描述】:

我有一个工作 Python 脚本从 csv 文件中提取单个变量替换脚本 {0} 中的单个值,然后它运行一个soapAPI调用,然后我想收集soap响应中的两个值CSV 文件。

这是运行我的脚本后的典型 Soap 响应..

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
   <SOAP-ENV:Header/>
   <SOAP-ENV:Body>
      <ns6:GetDeviceParameterValuesResponse xmlns:ns2="http://twowire.com/dmc/apps/nbiws/base/v1_0" xmlns:ns3="http://twowire.com/dmc/apps/nbiws/auditmgmt/v1_0" xmlns:ns4="http://twowire.com/dmc/apps/nbiws/configurationmgmt/v1_0" xmlns:ns5="http://twowire.com/dmc/apps/nbiws/devicediagnostics/v1_0" xmlns:ns6="http://twowire.com/dmc/apps/nbiws/devicemgmt/v1_0" xmlns:ns7="http://twowire.com/dmc/apps/nbiws/groupmgmt/v1_0" xmlns:ns8="http://twowire.com/dmc/apps/nbiws/subscribermgmt/v1_0" xmlns:ns9="http://twowire.com/dmc/apps/nbiws/workflowmgmt/v1_0">
         <ns6:parameterValue>
            <ns2:name>InternetGatewayDevice.DeviceInfo.UpTime</ns2:name>
            <ns2:value>3414</ns2:value>
         </ns6:parameterValue>
      </ns6:GetDeviceParameterValuesResponse>
   </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

我希望以下两个值都出现在 csv 中 名称 --> InternetGatewayDevice.DeviceInfo.UpTime(A 列) 值 --> 3414(B 列)

我相信我在将 xml 转换为 python dict 过程时遇到了问题(只是想不通)

我最终得到了一个生成的 csv 文件,但没有其他数据 image of generated csv file

这是工作的 Python SoapAPI 脚本

 #!/usr/bin/env python

import requests
import csv
import getopt
import sys
import time
import xml.etree.ElementTree as ET
import xmltodict

from lxml import objectify

xml_string = """<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"><SOAP-ENV:Header/><SOAP-ENV:Body><ns6:GetDeviceParameterValuesResponse xmlns:ns2="http://twowire.com/dmc/apps/nbiws/base/v1_0" xmlns:ns3="http://twowire.com/dmc/apps/nbiws/auditmgmt/v1_0" xmlns:ns4="http://twowire.com/dmc/apps/nbiws/configurationmgmt/v1_0" xmlns:ns5="http://twowire.com/dmc/apps/nbiws/devicediagnostics/v1_0" xmlns:ns6="http://twowire.com/dmc/apps/nbiws/devicemgmt/v1_0" xmlns:ns7="http://twowire.com/dmc/apps/nbiws/groupmgmt/v1_0" xmlns:ns8="http://twowire.com/dmc/apps/nbiws/subscribermgmt/v1_0" xmlns:ns9="http://twowire.com/dmc/apps/nbiws/workflowmgmt/v1_0"><ns6:parameterValue><ns2:name>InternetGatewayDevice.DeviceSummary</ns2:name><ns2:value>InternetGatewayDevice:1.4[](Baseline:1,Time:1,IPPing:1,CaptivePortal:1,TraceRoute:1,EthernetLAN:1,WiFiLAN:1,DeviceAssociation:2),VoiceService:1.0[1](Baseline:1)</ns2:value></ns6:parameterValue></ns6:GetDeviceParameterValuesResponse></SOAP-ENV:Body></SOAP-ENV:Envelope>"""
xml_object = objectify.fromstring(xml_string)
print xml_object.__dict__

def read_run(url, csv_file):
    csv_reader = csv.reader(open(csv_file))
    for row in csv_reader:
        print row
        if len(row) == 1:
            serial_number = row[0]
            GetParameterValues_element(url, serial_number)
        elif len(row) == 1:
            print ' [serial_number] format provided, associate element with specified subscriber'
            serial_number = row[0]
            GetParameterValues_element(url, serial_number)
        else:
            print 'Invalid csv file provided'
            print 'Only support below format'
            print 'serial_number'
            sys.exit(0)
    print 'Complete All GPV.'


def GetParameterValues_element(url, serial_number):
    request = u"""<soapenv:Envelope
        xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
        xmlns:v1="http://twowire.com/dmc/apps/nbiws/devicemgmt/v1_0"
        xmlns:v11="http://twowire.com/dmc/apps/nbiws/base/v1_0"
        xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
       <soapenv:Header>
<wsse:Security>
        <wsse:UsernameToken>
           <wsse:Username>unHERE</wsse:Username>
           <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">pwHERE</wsse:Password>
        </wsse:UsernameToken>
     </wsse:Security>
</soapenv:Header>
     <soapenv:Body>
      <v1:GetDeviceParameterValuesRequest>
         <v1:deviceSelector xsi:type="v11:SerialNumberAndOUIDeviceSelector" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
            <v11:serialNumber>184795206106368</v11:serialNumber>
            <v11:oui>0000C5</v11:oui>
         </v1:deviceSelector>
         <!--1 or more repetitions:-->
         <v1:parameterName>{0}</v1:parameterName>
         <v1:timeout>
            <v11:value>5</v11:value>
            <v11:units>MINUTES</v11:units>
         </v1:timeout>
      </v1:GetDeviceParameterValuesRequest>
   </soapenv:Body>
</soapenv:Envelope>""".format(serial_number)
    soap_request(url, request)


def soap_request(url, request):
    encoded_request = request.encode('utf-8')
    headers = {'Content-Type': 'text/xml'}
    response = requests.post(url=url, headers=headers, data=encoded_request, verify=False)
    #print response.content
    print response.content
    write_csv(response.content)
    
def write_csv(data):
    field_names = ["name"]
    with open("testoutput.csv", "w") as f:
        writer = csv.DictWriter(f, field_names)
    
        collected_items = [
          {
              "name": "value",
         },
        ]
    
        # Write a header row
        writer.writerow({x: x for x in field_names})
    
        for item_property_dict in collected_items:
            writer.writerow(item_property_dict)
    

if __name__ == '__main__':
    opts, args = getopt.getopt(sys.argv[1:], 'hu:f:', ['url=', 'file=', 'help'])

    sample_file = 'sample.csv'
    soap_url = 'http://poc5.servername.online/dmc-nbiws/'
    for k, v in opts:
        if k in ['-h', '--help']:
            print 'Usage :'
            print '-h or --help\t Display script usage'
            print '-u or --url\t The URL of Soap request, if it is not provided, using szeco142 by default'
            print """-f or --file\t Sample data file, must be a csv file,
                  if it is not provided, using /opt/sample.csv by default"""
            sys.exit(0)

        if k in ['-u', '--url']:
            soap_url = v

        if k in ['-f', '--file']:
            sample_file = v

    print soap_url
    print sample_file
    read_run(soap_url, sample_file)

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
   <SOAP-ENV:Header/>
   <SOAP-ENV:Body>
      <ns6:GetDeviceParameterValuesResponse xmlns:ns2="http://twowire.com/dmc/apps/nbiws/base/v1_0" xmlns:ns3="http://twowire.com/dmc/apps/nbiws/auditmgmt/v1_0" xmlns:ns4="http://twowire.com/dmc/apps/nbiws/configurationmgmt/v1_0" xmlns:ns5="http://twowire.com/dmc/apps/nbiws/devicediagnostics/v1_0" xmlns:ns6="http://twowire.com/dmc/apps/nbiws/devicemgmt/v1_0" xmlns:ns7="http://twowire.com/dmc/apps/nbiws/groupmgmt/v1_0" xmlns:ns8="http://twowire.com/dmc/apps/nbiws/subscribermgmt/v1_0" xmlns:ns9="http://twowire.com/dmc/apps/nbiws/workflowmgmt/v1_0">
         <ns6:parameterValue>
            <ns2:name>InternetGatewayDevice.DeviceInfo.UpTime</ns2:name>
            <ns2:value>76689</ns2:value>
         </ns6:parameterValue>
         <ns6:parameterValue>
            <ns2:name>InternetGatewayDevice.DeviceInfo.MemoryStatus.Total</ns2:name>
            <ns2:value>484420</ns2:value>
         </ns6:parameterValue>
         <ns6:parameterValue>
            <ns2:name>InternetGatewayDevice.DeviceInfo.FirstUseDate</ns2:name>
            <ns2:value>1970-01-01T00:09:43Z</ns2:value>
         </ns6:parameterValue>
      </ns6:GetDeviceParameterValuesResponse>
   </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

当我通过 pprint 运行以下命令时,我收到以下错误“Traceback(最近一次调用最后一次): 文件“./test_soap.py”,第 27 行,在 pprint(xml_object['SOAP-ENV:Envelope']['SOAP-ENV:Body']['ns6:GetDeviceParameterValuesResponse']['ns6:parameterValue']['ns2:name']) TypeError: 列表索引必须是整数,而不是 str"

因为我有多个参数参数返回具有相同的标签ns2和ns6

enter image description here

【问题讨论】:

    标签: python python-2.7 soap


    【解决方案1】:

    我能够在您的示例中使用以下内容解析您的 xml_string,还提供了一个解析出您需要的最终数据示例的示例;

    import xmltodict
    from pprint import pprint
    
        xml_string = """<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"><SOAP-ENV:Header/><SOAP-ENV:Body><ns6:GetDeviceParameterValuesResponse xmlns:ns2="http://twowire.com/dmc/apps/nbiws/base/v1_0" xmlns:ns3="http://twowire.com/dmc/apps/nbiws/auditmgmt/v1_0" xmlns:ns4="http://twowire.com/dmc/apps/nbiws/configurationmgmt/v1_0" xmlns:ns5="http://twowire.com/dmc/apps/nbiws/devicediagnostics/v1_0" xmlns:ns6="http://twowire.com/dmc/apps/nbiws/devicemgmt/v1_0" xmlns:ns7="http://twowire.com/dmc/apps/nbiws/groupmgmt/v1_0" xmlns:ns8="http://twowire.com/dmc/apps/nbiws/subscribermgmt/v1_0" xmlns:ns9="http://twowire.com/dmc/apps/nbiws/workflowmgmt/v1_0"><ns6:parameterValue><ns2:name>InternetGatewayDevice.DeviceSummary</ns2:name><ns2:value>InternetGatewayDevice:1.4[](Baseline:1,Time:1,IPPing:1,CaptivePortal:1,TraceRoute:1,EthernetLAN:1,WiFiLAN:1,DeviceAssociation:2),VoiceService:1.0[1](Baseline:1)</ns2:value></ns6:parameterValue></ns6:GetDeviceParameterValuesResponse></SOAP-ENV:Body></SOAP-ENV:Envelope>"""
    xml_object = xmltodict.parse(xml_string)
    pprint(xml_object)
    pprint(xml_object['SOAP-ENV:Envelope']['SOAP-ENV:Body']['ns6:GetDeviceParameterValuesResponse']['ns6:parameterValue']['ns2:name'])
    
    

    这对我来说的输出是;

    OrderedDict([('SOAP-ENV:Envelope',
                  OrderedDict([('@xmlns:SOAP-ENV',
                                'http://schemas.xmlsoap.org/soap/envelope/'),
                               ('SOAP-ENV:Header', None),
                               ('SOAP-ENV:Body',
                                OrderedDict([('ns6:GetDeviceParameterValuesResponse',
                                              OrderedDict([('@xmlns:ns2',
                                                            'http://twowire.com/dmc/apps/nbiws/base/v1_0'),
                                                           ('@xmlns:ns3',
                                                            'http://twowire.com/dmc/apps/nbiws/auditmgmt/v1_0'),
                                                           ('@xmlns:ns4',
                                                            'http://twowire.com/dmc/apps/nbiws/configurationmgmt/v1_0'),
                                                           ('@xmlns:ns5',
                                                            'http://twowire.com/dmc/apps/nbiws/devicediagnostics/v1_0'),
                                                           ('@xmlns:ns6',
                                                            'http://twowire.com/dmc/apps/nbiws/devicemgmt/v1_0'),
                                                           ('@xmlns:ns7',
                                                            'http://twowire.com/dmc/apps/nbiws/groupmgmt/v1_0'),
                                                           ('@xmlns:ns8',
                                                            'http://twowire.com/dmc/apps/nbiws/subscribermgmt/v1_0'),
                                                           ('@xmlns:ns9',
                                                            'http://twowire.com/dmc/apps/nbiws/workflowmgmt/v1_0'),
                                                           ('ns6:parameterValue',
                                                            OrderedDict([('ns2:name',
                                                                          'InternetGatewayDevice.DeviceSummary'),
                                                                         ('ns2:value',
                                                                          'InternetGatewayDevice:1.4[](Baseline:1,Time:1,IPPing:1,CaptivePortal:1,TraceRoute:1,EthernetLAN:1,WiFiLAN:1,DeviceAssociation:2),VoiceService:1.0[1](Baseline:1)')]))]))]))]))])
    
    
    'InternetGatewayDevice.DeviceSummary'
    
    

    【讨论】:

    • 非常感谢。 !你真的帮助我向前迈进了我能够复制你的结果。我还有一个问题,在示例中,我提供它只返回一个参数,但在现实世界中它将有多个具有相同名称空间的参数 rtrn.. 示例。
    • 抱歉,刚刚收到关于您的评论的电子邮件。因此,如果单个 json 键返回多个结果,那么它们应该作为 python 列表返回。因此,您可以以这种格式使用它们。如果你给我一个直接的例子,那么我可以给你一个更好的答案。
    猜你喜欢
    • 2017-09-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-07
    • 2021-05-08
    • 2017-06-02
    • 2023-04-08
    • 1970-01-01
    相关资源
    最近更新 更多