2014-12-16 4 views
2

У меня есть следующий XML-файл:Разбор данных для XML-файла в Python

<address addr="x.x.x.x" addrtype="ipv4"/> 
<hostnames> 
</hostnames> 
<ports><port protocol="tcp" portid="1"><state state="open" reason="syn-ack" reason_ttl="0"/><service name="tcpmux" method="table" conf="3"/></port> 
<port protocol="tcp" portid="64623"><state state="open" reason="syn-ack" reason_ttl="0"/><service name="unknown" method="table" conf="3"/></port> 
</ports> 
<times srtt="621179" rttvar="35357" to="762607"/> 
</host> 
<host starttime="1418707433" endtime="1418707742"><status state="up" reason="syn-ack" reason_ttl="0"/> 
<address addr="y.y.y.y" addrtype="ipv4"/> 
<hostnames> 
</hostnames> 
<ports><port protocol="tcp" portid="1"><state state="open" reason="syn-ack" reason_ttl="0"/><service name="tcpmux" method="table" conf="3"/></port> 
<port protocol="tcp" portid="64680"><state state="open" reason="syn-ack" reason_ttl="0"/><service name="unknown" method="table" conf="3"/></port> 
</ports> 
<times srtt="834906" rttvar="92971" to="1206790"/> 
</host> 
<host starttime="1418707433" endtime="1418707699"><status state="up" reason="syn-ack" reason_ttl="0"/> 
<address addr="w.w.w.w" addrtype="ipv4"/> 
<hostnames> 
</hostnames> 
<ports><extraports state="filtered" count="997"> 
<extrareasons reason="no-responses" count="997"/> 
</extraports> 
<port protocol="tcp" portid="25"><state state="open" reason="syn-ack" reason_ttl="0"/><service name="smtp" method="table" conf="3"/></port> 
<port protocol="tcp" portid="443"><state state="open" reason="syn-ack" reason_ttl="0"/><service name="https" method="table" conf="3"/></port> 
<port protocol="tcp" portid="7443"><state state="open" reason="syn-ack" reason_ttl="0"/><service name="oracleas-https" method="table" conf="3"/></port> 
</ports> 
<times srtt="690288" rttvar="110249" to="1131284"/> 
</host> 

То, что я попытался для извлечения данных для каждого IP является:

import sys 
import xml.etree.ElementTree as ET 
input=sys.argv[1] 

tree=ET.parse(input) 
root=tree.getroot() 

for host in root.findall('host'): 
    updown=host.find('status').get('state') 
    if updown=='up': 
     print 'IP Address: '+host.find('address').get('addr') 
     ports=[port.get('portid') for port in root.findall('.//port')] 
     state=[port.get('state') for port in root.findall('.//port/state')] 
     name=[port.get('name') for port in root.findall('.//port/service')] 

Но он возвращает мне всю информацию изобр , Как я могу получить конкретную информацию для каждого IP-адреса?

Я думаю, что я должен изменить root.findall, но я не знаю, как я могу это сделать.

ответ

1

Для меня этот код кажется suspiсious:

 ports=[port.get('portid') for port in root.findall('.//port')] 
     state=[port.get('state') for port in root.findall('.//port/state')] 
     name=[port.get('name') for port in root.findall('.//port/service')] 

Внутри цикла, вы ищете весь корневой узел ".// порт ... материал.
Кажется, вам это нужно:

 ports=[port.get('portid') for port in host.findall('.//port')] 
     state=[port.get('state') for port in host.findall('.//port/state')] 
     name=[port.get('name') for port in host.findall('.//port/service')] 
2

В цикле просто изменить root.findall() к host.findall():

for host in root.findall('host'): 
    updown=host.find('status').get('state') 
    if updown=='up': 
     print 'IP Address: '+host.find('address').get('addr') 
     ports=[port.get('portid') for port in host.findall('.//port')] 
     state=[port.get('state') for port in host.findall('.//port/state')] 
     name=[port.get('name') for port in host.findall('.//port/service')] 

Это позволит ограничить нахождение портов, состояния и имена тех, кто в каждом узле, а не те, жгутов весь XML-документ.

+0

Большое спасибо – MLSC

1

Указав

root.findall('.//port') 

Вы снова, начиная с корня документа, следовательно, все порты возвращаются.

ports=[port.get('portid') for port in host.findall('./ports/port')] 
+1

Спасибо за ответ – MLSC

Смежные вопросы