Ключ элемента вывода NMAP XML Python для синтаксического анализа = NodeList

Я пытаюсь проанализировать конкретное значение из XML-файла NMAP. Часть xml-файла выглядит так:

<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

Заранее спасибо!


person user1781482    schedule 20.10.2015    source источник
comment
Используете ли вы модуль lxml? Если это так, он разрешает XPath: //elem[key='os']   -  person Parfait    schedule 20.10.2015
comment
Использование xml.dom.minidom   -  person user1781482    schedule 20.10.2015
comment
Учтите, что lxml как minidom ограничен в запросах XML по узлам и атрибутам.   -  person Parfait    schedule 21.10.2015


Ответы (1)


Может быть, что-то вроде этого:

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' ) )
person sls    schedule 06.06.2016
comment
Хорошо... Первоначальный постер пытался читать XML-файлы Nmap. Эти файлы грязные. Скрипты заполняют XML любой информацией, которую они сочтут важной. Оригинальный плакат пытался справиться с этим на уровне XML, используя инструменты поиска DOM. Вместо того, чтобы работать на уровне XML, в примере, который я привел, просто берется весь XML и помещается в объект класса. Затем на высоком уровне, в Python, вы можете получить части и отформатировать их по мере необходимости. В частности, если вы используете метод getattr, который допускает отсутствующие значения и предоставляет значение по умолчанию. - person sls; 21.06.2016