@idasaubaevayan

Как вывести нужные данные с XML файла Python скриптом?

Нужно записать в текстовый файл ip адрес (например из строки <address addr="45.33.49.119" addrtype="ipv4"/>) и версию ОС ( например из строки <cpe>cpe:/h:hp:p2000_g3</cpe>. В файле несколько строк с инфой про ОС, нужен именно первый вывод).

В таком формат:
45.33.49.119 : cpe:/h:hp:p2000_g3

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE nmaprun>
<?xml-stylesheet href="file:///usr/bin/../share/nmap/nmap.xsl" type="text/xsl"?>
<!-- Nmap 7.80 scan initiated Fri Oct 16 04:52:18 2020 as: nmap -O -oX xml_data.xml 45.33.49.119 -->
<nmaprun scanner="nmap" args="nmap -O -oX xml_data.xml 45.33.49.119" start="1602823938" startstr="Fri Oct 16 04:52:18 2020" version="7.80" xmloutputversion="1.04">
<scaninfo type="syn" protocol="tcp" numservices="1000" services="1,3-4,6-7,9,13,17,19-26,30,32-33,37,42-43,49,53,70,79-85,88-90,99-100,106,109-111,113,119,125,135,139,143-144,146,161,163,179,199,211-212,22>
<verbose level="0"/>
<debugging level="0"/>
<host starttime="1602823938" endtime="1602823972"><status state="up" reason="reset" reason_ttl="64"/>
<address addr="45.33.49.119" addrtype="ipv4"/>
<hostnames>
<hostname name="ack.nmap.org" type="PTR"/>
</hostnames>
<ports><extraports state="filtered" count="993">
<extrareasons reason="no-responses" count="993"/>
</extraports>
<port protocol="tcp" portid="22"><state state="open" reason="syn-ack" reason_ttl="51"/><service name="ssh" method="table" conf="3"/></port>
<port protocol="tcp" portid="25"><state state="open" reason="syn-ack" reason_ttl="51"/><service name="smtp" method="table" conf="3"/></port>
<port protocol="tcp" portid="70"><state state="closed" reason="reset" reason_ttl="51"/><service name="gopher" method="table" conf="3"/></port>
<port protocol="tcp" portid="80"><state state="open" reason="syn-ack" reason_ttl="50"/><service name="http" method="table" conf="3"/></port>
<port protocol="tcp" portid="113"><state state="closed" reason="reset" reason_ttl="51"/><service name="ident" method="table" conf="3"/></port>
<port protocol="tcp" portid="443"><state state="open" reason="syn-ack" reason_ttl="50"/><service name="https" method="table" conf="3"/></port>
<port protocol="tcp" portid="31337"><state state="closed" reason="reset" reason_ttl="51"/><service name="Elite" method="table" conf="3"/></port>
</ports>
<os><portused state="open" proto="tcp" portid="22"/>
<portused state="closed" proto="tcp" portid="70"/>
<osmatch name="HP P2000 G3 NAS device" accuracy="91" line="34647">
<osclass type="storage-misc" vendor="HP" osfamily="embedded" accuracy="91"><cpe>cpe:/h:hp:p2000_g3</cpe></osclass>
</osmatch>
<osmatch name="Linux 2.6.32" accuracy="90" line="55409">
<osclass type="general purpose" vendor="Linux" osfamily="Linux" osgen="2.6.X" accuracy="90"><cpe>cpe:/o:linux:linux_kernel:2.6.32</cpe></osclass>
</osmatch>
<osmatch name="Linux 2.6.32 - 3.1" accuracy="90" line="56315">
<osclass type="general purpose" vendor="Linux" osfamily="Linux" osgen="2.6.X" accuracy="90"><cpe>cpe:/o:linux:linux_kernel:2.6</cpe></osclass>
<osclass type="general purpose" vendor="Linux" osfamily="Linux" osgen="3.X" accuracy="90"><cpe>cpe:/o:linux:linux_kernel:3</cpe></osclass>
</osmatch>
<osmatch name="Ubiquiti AirMax NanoStation WAP (Linux 2.6.32)" accuracy="90" line="61488">
<osclass type="WAP" vendor="Linux" osfamily="Linux" osgen="2.6.X" accuracy="90"><cpe>cpe:/o:linux:linux_kernel:2.6.32</cpe></osclass>
<osclass type="WAP" vendor="Ubiquiti" osfamily="embedded" accuracy="90"><cpe>cpe:/h:ubnt:airmax_nanostation</cpe></osclass>
</osmatch>
<osmatch name="Linux 3.7" accuracy="90" line="65676">
<osclass type="general purpose" vendor="Linux" osfamily="Linux" osgen="3.X" accuracy="90"><cpe>cpe:/o:linux:linux_kernel:3.7</cpe></osclass>
</osmatch>
<osmatch name="Linux 2.6.32 - 3.13" accuracy="89" line="56411">
<osclass type="general purpose" vendor="Linux" osfamily="Linux" osgen="2.6.X" accuracy="89"><cpe>cpe:/o:linux:linux_kernel:2.6</cpe></osclass>
<osclass type="general purpose" vendor="Linux" osfamily="Linux" osgen="3.X" accuracy="89"><cpe>cpe:/o:linux:linux_kernel:3</cpe></osclass>
</osmatch>
<osmatch name="Linux 3.0 - 3.2" accuracy="89" line="62456">
<osclass type="general purpose" vendor="Linux" osfamily="Linux" osgen="3.X" accuracy="89"><cpe>cpe:/o:linux:linux_kernel:3</cpe></osclass>
</osmatch>
<osmatch name="Linux 3.3" accuracy="89" line="65197">
<osclass type="general purpose" vendor="Linux" osfamily="Linux" osgen="3.X" accuracy="89"><cpe>cpe:/o:linux:linux_kernel:3.3</cpe></osclass>
</osmatch>
<osmatch name="Infomir MAG-250 set-top box" accuracy="89" line="59437">
<osclass type="media device" vendor="Linux" osfamily="Linux" osgen="2.6.X" accuracy="89"><cpe>cpe:/o:linux:linux_kernel:2.6</cpe></osclass>
<osclass type="media device" vendor="Infomir" osfamily="embedded" accuracy="89"><cpe>cpe:/h:infomir:mag-250</cpe></osclass>
</osmatch>
<osmatch name="Ubiquiti Pico Station WAP (AirOS 5.2.6)" accuracy="88" line="102825">
<osclass type="WAP" vendor="Ubiquiti" osfamily="AirOS" osgen="5.X" accuracy="88"><cpe>cpe:/o:ubnt:airos:5.2.6</cpe></osclass>
</osmatch>
</os>
<uptime seconds="751775" lastboot="Wed Oct  7 12:03:18 2020"/>
<tcpsequence index="256" difficulty="Good luck!" values="5833A5A,D5206F79,8E66294D,8E3B0632,AC2DB44A,7F486476"/>
<ipidsequence class="All zeros" values="0,0,0,0,0,0"/>
<tcptssequence class="1000HZ" values="2CCF1F79,2CCF1FD4,2CCF2043,2CCF209E,2CCF2102,2CCF2164"/>
<times srtt="193340" rttvar="78390" to="506900"/>
</host>
<runstats><finished time="1602823973" timestr="Fri Oct 16 04:52:53 2020" elapsed="34.33" summary="Nmap done at Fri Oct 16 04:52:53 2020; 1 IP address (1 host up) scanned in 34.33 seconds" exit="success"/><>
</runstats>
</nmaprun>
  • Вопрос задан
  • 1395 просмотров
Пригласить эксперта
Ответы на вопрос 3
fox_12
@fox_12 Куратор тега Python
Расставляю биты, управляю заряженными частицами
from lxml import etree

xml = '''ВАШ XML'''

parser = etree.XMLParser(
    encoding='utf-8',
    recover=True,
)
root = etree.fromstring(xml.encode(), parser=parser)
address = root.xpath('.//address')[0].get('addr')
cpe = root.xpath('.//cpe')
for im in cpe:
    print(f'{address} : {im.text}')

45.33.49.119 : cpe:/h:hp:p2000_g3
45.33.49.119 : cpe:/o:linux:linux_kernel:2.6.32
45.33.49.119 : cpe:/o:linux:linux_kernel:2.6
45.33.49.119 : cpe:/o:linux:linux_kernel:3
45.33.49.119 : cpe:/o:linux:linux_kernel:2.6.32
45.33.49.119 : cpe:/h:ubnt:airmax_nanostation
45.33.49.119 : cpe:/o:linux:linux_kernel:3.7
45.33.49.119 : cpe:/o:linux:linux_kernel:2.6
45.33.49.119 : cpe:/o:linux:linux_kernel:3
45.33.49.119 : cpe:/o:linux:linux_kernel:3
45.33.49.119 : cpe:/o:linux:linux_kernel:3.3
45.33.49.119 : cpe:/o:linux:linux_kernel:2.6
45.33.49.119 : cpe:/h:infomir:mag-250
45.33.49.119 : cpe:/o:ubnt:airos:5.2.6

Если нужен только первый- то вместо цикла:
print(f'{address} : {cpe[0].text}')
45.33.49.119 : cpe:/h:hp:p2000_g3
Ответ написан
@PavelMos
xpath ругается что файл некорректный, нужно вручную некоторые теги править. Если он таким образом всё время создаётся, хотя это странно, то проще использовать для разбора не xpath, а какой-то другой парсер вроде Beautiful Soup или регулярные выражения
для адреса:
addr=\"(([0-9]{1,3}[\\.]){3}[0-9]{1,3})\" #результат в группе 1, т.е. второй по счёту, т.к. первым элементом будет результат найденного по всему выражению, а не по его подгруппам
a=re.search( addr_reg, text)[1]
https://regex101.com/r/VylVkU/2
для cpe
osmatch\sname=\"(.?HP.+?)\".*\n.*(.+?)< #результат будет в группе 2, то есть третьей по счёту
https://regex101.com/r/VylVkU/1

import re
f=open("....")
text=f.read()
addr='addr=\\"(([0-9]{1,3}[\\.]){3}[0-9]{1,3})"'
a=re.search(addr, text)[1] #re.search выдает набор: весь  результат и подргуппы, нужна конкретная подгруппа, в которой адрес, аналогично со вторым re.search
cpe="osmatch\sname=\"(.?HP.+?)\".*\n.*<cpe>(.+?)<"
c=re.search(cpe, text)[2]
print (a,c)
45.33.49.119 cpe:/h:hp:p2000_g3
Ответ написан
файл был немножко битый (во время копирования)
вот пример
from __future__ import print_function
import re
from xml.dom import minidom


xmldoc = minidom.parseString(data.strip())
nodes = xmldoc.getElementsByTagName('cpe')
print(nodes[0].firstChild.data)
nodes = xmldoc.getElementsByTagName('address')
print (nodes[0].attributes['addr'].value)


cpe:/h:hp:p2000_g3
45.33.49.119
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы