2015-10-20 61 views
0

我想解析NMAP XML文件中的特定值。 xml文件的部分看起來像這樣:Python解析NMAP XML輸出「elem key =」NodeList

<nmaprun scanner="nmap" args="nmap -A -P0 -oA scanoutput 192.168.1.5" start="1445258532" startstr="Mon Oct 19 08:42:12 2015" version="6.47" xmloutputversion="1.04"> 
    <hostscript> 
     <script id="smb-os-discovery" output="&#10; OS: Windows Server 2008 R2 Standard 7601 Service Pack 1 (Windows Server 2008 R2 Standard 6.1)&#10; OS CPE: cpe:/o:microsoft:windows_server_2008::sp1&#10; Computer name: SOMEHOSTNAME&#10; NetBIOS computer name: SOMEHOSTNAME&#10; Domain name: domain.local&#10; Forest name: domain.local&#10; FQDN: SOMEHOSTNAME.domain.local&#10; System time: 2015-10-19T08:50:07-04:00&#10;"> 
      <elem key="os">Windows Server 2008 R2 Standard 7601 Service Pack 1</elem> 
      <elem key="lanmanager">Windows Server 2008 R2 Standard 6.1</elem> 
      <elem key="server">SOMEHOSTNAME\x00</elem> 
      <elem key="date">2015-10-19T08:50:07-04:00</elem> 
      <elem key="fqdn">SOMEHOSTNAME.domain.local</elem> 
      <elem key="domain_dns">domain.local</elem> 
      <elem key="forest_dns">domain.local</elem> 
      <elem key="workgroup">HOME\x00</elem> 
      <elem key="cpe">cpe:/o:microsoft:windows_server_2008::sp1</elem> 
     </script> 
    </hostscript> 
</nmaprun> 

我想從每個鍵的值,但不知道如何解決它。例如,如何從得到的值elem key =「os」?到目前爲止,我可以得到完整的輸出,但是當我將它添加到CSV中時,它會變得雜亂,我需要分別將每個值分開。下面是我的代碼有:

serveros = [script.getAttribute('output') for script in hosttag.getElementsByTagName('script') if script.getAttribute('id') == 'smb-os-discovery'] 

如果我將其更改爲:

serveros = [script.getElementsByTagName('os') for script in hosttag.getElementsByTagName('script') if script.getAttribute('id') == 'smb-os-discovery'] 

我得到這個錯誤:

TypeError: sequence item 0: expected string, NodeList found 

提前感謝!

+0

是否使用[LXML(http://lxml.de/)模塊?如果是這樣,它允許XPath:'// elem [key ='os']' – Parfait

+0

使用xml.dom.minidom – user1781482

+0

那麼考慮,lxml作爲[minidom](http://stackoverflow.com/questions/12815637/python- minidom-xml-query)受節點和屬性查詢XML的限制。 – Parfait

回答

0

也許是這樣的:

class ScriptResult: 
    def __init__(self, script, port_number): 
     self.port_number = port_number 
     for k,v in script.attrib.iteritems(): 
      self.__dict__[k] = v 
     return 

    def __str__(self): 
     d = '\n' 
     for k,v in self.__dict__.iteritems(): 
      d += ' %-30s : %s\n' % (k,v) 
     return "ScriptResult(%s)\n" % d 

class Host: 
    def __init__(self): 
     self.script_results = [] # define list of script results 
     return 

    def print_results(self): 
     for i in self.script_results: 
      print i 
     return 


class XML_Parser: 

    def get_hostscripts(self, host, xml_host_element): 
     for hs in xml_host_element.findall('hostscript'): 
      for s in hs.findall('script'): 
       host.script_results.append(ScriptResult(s, 'host')) 
+0

你應該解釋這是如何工作的。 – Laurel

+0

好的...原始海報試圖讀取Nmap XML文件。這些文件很混亂。腳本用任何他們認爲重要的信息填充XML。原始海報試圖使用DOM findall工具在XML級別處理此問題。我所提供的例子不是在XML層面上工作,而是將所有XML都放到一個類對象中。然後在Python的高層次上,你可以根據需要獲取並設置它們的格式。特別是如果您使用可以容忍缺失值並提供默認值的getattr方法。 – sls

+0

'self.analyze_script_smb_os_discovery(項目,S,SCRIPT_NAME,script_output) 高清analyze_script_smb_os_discovery(個體經營,項目,S,SCRIPT_NAME,script_output): 如果SCRIPT_NAME = 'SMB-OS-發現': 回報 script_output = script_output.strip ()[i] [0] .strip(),i [2] .strip()() odist = [i.partition(':')for script_output.split('\ n')] ))爲我在olist])' – sls