2017-04-05 72 views
1

我對Python編碼很陌生,在嘗試升級某些代碼時遇到了問題。我正在與一個應用程序通過API從掃描存儲的數據中提取數據。AttributeError:'unicode'對象沒有屬性'key'

這裏是代碼,因爲它坐落工作

def _collect_one_host_scan_info(self, host_id, sid, scan_info): 
    """ 
    The method to collect all the vulnerabilities of one host and generate the event data. 
    """ 
    count = 0 
    host_uri = self.endpoint + '/' + str(sid) + '/hosts/' + str(host_id) 
    result = self.client.request(host_uri).get("content") 
    # if there is exception in request, return None 
    if result is None: 
     _LOGGER.info("There is exception in request, return None") 
     return None 
    else: 
     host_info = result.get("info", {}) 
     host_end_time = host_info.get("host_end", "") 
     if self.ckpt.is_new_host_scan(host_end_time, 
             self.config.get("start_date")): 
      self.source = self.url + self.endpoint + '/' + str(
       sid) + '/hosts/' + str(host_id) 
      for vuln in result.get("vulnerabilities", []): 
       vuln["sid"] = sid 
       vuln["host_id"] = host_id 

       #get the port info 
       plugin_id = vuln.get("plugin_id", "") 
       port_info = [] 
       if plugin_id: 
        plugin_uri = "{}/plugins/{}".format(host_uri, 
                 plugin_id) 
        plugin_outputs = self.client.request(plugin_uri).get(
         "content", {}).get("outputs") 
        ports = [] 
        for output in plugin_outputs: 
         ports.extend(output.get("ports", {}).keys()) 
        for port in ports: 
         port_elem = {} 
         port_items = re.split(r"\s*/\s*", port) 
         port_elem["port"] = int(port_items[0]) 
         if port_items[1]: 
          port_elem["transport"] = port_items[1] 
         if port_items[2]: 
          port_elem["protocol"] = port_items[2] 
         port_info.append(port_elem) 

       vuln = dict(vuln, **scan_info) 
       vuln = dict(vuln, **host_info) 
       if port_info: 
        vuln["ports"] = port_info 
       entry = NessusObject(
        vuln.get("timestamp"), self.sourcetype, self.source, 
        vuln) 
       self._print_stream(entry) 
       count += 1 
    return count 

正從外觀拉這樣

"outputs": [ 
    { 
     "ports": { 
      "445/tcp/cifs": [ 
       { 
        "hostname": "computer.domain.com" 
       } 
      ] 
     }, 
     "has_attachment": 0, 
     "custom_description": null, 
     "plugin_output": "\nPath : c:\\program files (x86)\\folder\\bin\\fax.exe\nUsed by services : RFDB\nFile write allowed for groups : Domain Users\nFull control of directory allowed for groups : Domain Users\n\nPath : c:\\program files (x86)\\folder\\bin\\faxrpc.exe\nUsed by services : RFRPC\nFile write allowed for groups : Domain Users\nFull control of directory allowed for groups : Domain Users\n\nPath : c:\\program files (x86)\\folder\\bin\\faxserv.exe\nUsed by services : RFSERVER\nFile write allowed for groups : Domain Users\nFull control of directory allowed for groups : Domain Users\n`, 
     "hosts": null, 
     "severity": 3 
    } 

與工作代碼返回的數據

ports{}.port 445 
ports{}.protocol tcp 
ports{}.transport cifs 

我真正想要的是用「端口」數據獲取「plugin_output」數據

我目前只是想取代「端口」數據與「plugin_output」數據

#get the output info 
      plugin_id = vuln.get("plugin_id", "") 
      output_info = [] 
      if plugin_id: 
       plugin_uri = "{}/plugins/{}".format(host_uri, 
                plugin_id) 
       plugin_outputs = self.client.request(plugin_uri).get(
        "content", {}).get("outputs") 
       outputs = [] 
       for output in plugin_outputs: 
        outputs.extend(output.get("plugin_output", "").keys()) 
       for plugin in plugin_outputs: 
        plugin_elem = {} 
        plugin_items = re.split(r"nPath\s*", plugin) 
        plugin_elem["location1"] = plugin_items[0] 
        if plugin_items[1]: 
         plugin_elem["location2"] = plugin_items[1] 
        if plugin_items[2]: 
         plugin_elem["location3"] = plugin_items[2] 
        output_info.append(plugin_elem) 

      vuln = dict(vuln, **scan_info) 
      vuln = dict(vuln, **host_info) 
      if output_info: 
       vuln["plugin_output"] = output_info 
      entry = NessusObject(
       vuln.get("timestamp"), self.sourcetype, self.source, 
       vuln) 
      self._print_stream(entry) 
      count += 1 

我做了什麼,你可以看到,如果只是「plugin_output」數據取代「端口」數據並收到的錯誤是 AttributeError:'unicode'對象沒有屬性鍵

+0

JSON有時沒有「plugin_output」字段。 – grumpalot23

回答

0

好了經過進一步的努力,我能夠找出我需要做的代碼。這比我想象的要容易得多,但有時在學習一門新語言時很難設想需要什麼。代碼如下。

def _collect_one_host_scan_info(self, host_id, sid, scan_info): 
    """ 
    The method to collect all the vulnerabilities of one host and generate 
    the event data. 
    """ 
    count = 0 
    host_uri = self.endpoint + '/' + str(sid) + '/hosts/' + str(host_id) 
    result = self.client.request(host_uri).get("content") 
    # if there is exception in request, return None 
    if result is None: 
     _LOGGER.info("There is exception in request, return None") 
     return None 
    else: 
     host_info = result.get("info", {}) 
     host_end_time = host_info.get("host_end", "") 
     if self.ckpt.is_new_host_scan(host_end_time, 
             self.config.get("start_date")): 
      self.source = self.url + self.endpoint + '/' + str(
       sid) + '/hosts/' + str(host_id) 
      for vuln in result.get("vulnerabilities", []): 
       vuln["sid"] = sid 
       vuln["host_id"] = host_id 
       plugin_id = vuln.get("plugin_id", "") 

       # get plugin_output data 
       plugin_output_info = [] 
       if plugin_id: 
        plugin_uri = "{}/plugins/{}".format(host_uri, 
                 plugin_id) 
        plugin_outputs = self.client.request(plugin_uri).get(
         "content", {}).get("outputs", []) 
        data_output = [] 
        for output in plugin_outputs: 
         items = output.get("plugin_output", 'no value') 
         item = str(items) 
         #clean = re.sub('[^a-zA-Z0-9-()_*.(:\\)]', ' ', item) 
         plugin_output_info.append(item) 

       # get the port info   
       port_info = [] 
       if plugin_id: 
        plugin_uri = "{}/plugins/{}".format(host_uri, 
                 plugin_id) 
        plugin_outputs = self.client.request(plugin_uri).get(
         "content", {}).get("outputs", []) 
        ports = [] 
        for output in plugin_outputs: 
         ports.extend(output.get("ports", {}).keys()) 
        for port in ports: 
         port_elem = {} 
         port_items = re.split(r"\s*/\s*", port) 
         port_elem["port"] = int(port_items[0]) 
         if port_items[1]: 
          port_elem["transport"] = port_items[1] 
         if port_items[2]: 
          port_elem["protocol"] = port_items[2] 
         port_info.append(port_elem) 

       vuln = dict(vuln, **scan_info) 
       vuln = dict(vuln, **host_info) 
       if port_info: 
        vuln["ports"] = port_info 
       if plugin_output_info: 
        vuln["plugin_output"] = plugin_output_info 
       entry = NessusObject(
        vuln.get("timestamp"), self.sourcetype, self.source, 
        vuln) 
       self._print_stream(entry) 
       count += 1 
    return count