2013-10-10 71 views
1

我試圖從下面的XML文件中的一些元素(下調nmap輸出):解析nmap的XML報告與Python

<?xml version="1.0"?> 
<nmaprun> 
<host starttime="1381245200" endtime="1381245316"> 
    <address addr="192.168.1.5" addrtype="ipv4"/> 
    <hostnames> 
     <hostname name="host1.example.com" type="PTR"/> 
    </hostnames> 
    <os> 
     <osmatch> 
     <osclass type="general purpose" vendor="Linux" osfamily="Linux" osgen="2.6.X" accuracy="100"> 
      <cpe>cpe:/o:linux:linux_kernel:2.6</cpe> 
     </osclass> 
     </osmatch> 
    </os> 
    </host> 
</nmaprun> 

用下面的代碼:

import xml.etree.ElementTree as ET 

d = [ 
     {'path': 'address', 'el': 'addr'}, 
     {'path': 'hostnames/hostname', 'el': 'name'}, 
     {'path': 'os/osmatch/osclass', 'el': 'osfamily'} 
] 

tree = ET.parse('testnmap.xml') 
root = tree.getroot() 
for i in root.iter('host'): 
     for h in d: 
       if i.find(h['path']): print i.find(h['path']).get(h['el']) 
       else: print "UNKNOWN ", (h['path']) 

的想法是提取IP,主機名和操作系統。輸出給我

UNKNOWN address 
UNKNOWN hostnames/hostname 
Linux 

所以最裏面的路徑工作(osfamily),而其他(主機名)失敗。接觸他們的正確方法是什麼?

+1

作爲替代,可以考慮使用包括在分配使用nmap的Ndiff Python腳本解析器。它專門用於解析Nmap XML並在Python對象中返回結果。 – bonsaiviking

回答

1

我認爲問題是i.find(h['path'])的布爾比較。它檢查該元素是否有子元素,並且只發生在<osclass>。你必須檢查它是否爲空,比較None,如:

... 
e = i.find(h['path']) 
if e is not None: print(e.get(h['el'])) 
... 

它產生:

192.168.1.5 
host1.example.com 
Linux 
+0

我不知道我明白:調用'i.find(「os/osmatch/osclass」)'和'i.find(「主機名/主機名」)'之間有什麼區別,.get()之後達到在這兩種情況下,標籤內的元素(我的意思是他們從「」)獲得「aaa」值。你的代碼工作並解決問題 - 這只是我明白爲什麼它的工作原理:) – WoJ

+0

@Woj:據我所知,當一個元素存在但沒有子元素時,它返回'False',並且當元素不存在時返回'無'。在布爾上下文中,兩個值都被解釋爲「False」,因此需要使用「None」進行顯式檢查來過濾那些無法找到的元素。所以''因爲它沒有孩子而是'UNKNOWN',但''有一個,''。 – Birei

+0

現在一切都很清楚 - 我沒有意識到有兩個不同的值根據孩子的存在而返回,兩個'if'都是'if'。感謝您的澄清! – WoJ