Extracting data from xml format in python
Question: I have the following nmap output as xml format:

    
    
    <ports><extraports state="closed" count="991">
    <extrareasons reason="conn-refused" count="991"/>
    </extraports>
    <port protocol="tcp" portid="22"><state state="open" reason="syn-ack" reason_ttl="0"/><service name="ssh" method="table" conf="3"/></port>
    <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="139"><state state="open" reason="syn-ack" reason_ttl="0"/><service name="netbios-ssn" 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>
    

I want to get port numbers that are open:

    
    
    print 'Port Number: '+host.find('ports').find('port').get('portid')
    

But the result is just `22`.

How can I have the results:

    
    
    22
    25
    139
    443
    


Answer: Find all `port` elements, and get `portid` attributes.

Using
[`Element.findall`](https://docs.python.org/2/library/xml.etree.elementtree.html#xml.etree.ElementTree.Element.findall)
and [list
comprehension](https://docs.python.org/2/tutorial/datastructures.html#list-
comprehensions):

    
    
    >>> import xml.etree.ElementTree as ET
    >>> root = ET.fromstring('''
    <ports><extraports state="closed" count="991">
    <extrareasons reason="conn-refused" count="991"/>
    </extraports>
    <port protocol="tcp" portid="22"><state state="open" reason="syn-ack" reason_ttl="0"/><service name="ssh" method="table" conf="3"/></port>
    <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="139"><state state="open" reason="syn-ack" reason_ttl="0"/><service name="netbios-ssn" 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>
    </ports>
    ''')
    >>> [port.get('portid') for port in root.findall('.//port')]
    ['22', '25', '139', '443']
    

