简体   繁体   中英

How to get particular entry from value of dictionary in python

Here, this is value of my dictionary but I want to get only details like product and version of 443 and 80. Is there any way or command with the help of which, we can gethis info? Here is my dictionary value:

   {'nmap': {'scanstats': {'timestr': 'Fri Apr 17 05:08:18 2015', 'uphosts': '1', 'downhosts': '0', 'totalhosts': '1', 'elapsed': '14.91'}, 'scaninfo': {'tcp': {'services': '80,443', 'method': 'connect'}}, 'command_line': 'nmap -oX - -p 80,443 -sV xxxx'}, 'scan': {'x.x.x.x': {'status': {'state': 'up', 'reason': 'syn-ack'}, 'hostname': 'xxxx', 'vendor': {}, 'addresses': {'ipv4': '0x.x.x'}, 'tcp': {'443': {'product': 'Apache Tomcat/Coyote JSP engine', 'name': 'http', 'extrainfo': '', 'reason': 'syn-ack', 'cpe': '', 'state': 'open', 'version': '1.1', 'conf': '10'}, '80': {'product': 'Apache Tomcat/Coyote JSP engine', 'name': 'http', 'extrainfo': '', 'reason': 'syn-ack', 'cpe': '', 'state': 'open', 'version': '1.1', 'conf': '0'}}}}}

So. I ran this command

      scan=[v for k,v in x.iteritems() if 'scan' in k]

It gives me result below:

    [{
    'x.x.x.x': {
        'status': {
            'state': 'up',
            'reason': 'syn-ack'
        },
        'hostname': 'xxxx',
        'vendor': {},
        'addresses': {
            'ipv4': 'x.x.x.x'
        },
        'tcp': {
            '443': {
                'product': 'Apache Tomcat/Coyote JSP engine',
                'name': 'http',
                'extrainfo': '',
                'reason': 'syn-ack',
                'cpe': '',
                'state': 'open',
                'version': '1.1',
                'conf': '10'
            },
            '80': {
                'product': '',
                'name': 'http',
                'extrainfo': '',
                'reason': 'conn-refused',
                'cpe': '',
                'state': 'closed',
                'version': '',
                'conf': '3'
            }
        }
    }
}]

You can try the following:

>>> data = [{'x.x.x.x': {'status': {'state': 'up', 'reason': 'syn-ack'}, 'hostname': 'xxxx', 'vendor': {}, 'addresses': {'ipv4': 'x.x.x.x'}, 'tcp': {'443': {'product': 'Apache Tomcat/Coyote JSP engine', 'name': 'http', 'extrainfo': '', 'reason': 'syn-ack', 'cpe': '', 'state': 'open', 'version': '1.1', 'conf': '10'}, '80': {'product': '', 'name': 'http', 'extrainfo': '', 'reason': 'conn-refused', 'cpe': '', 'state': 'closed', 'version': '', 'conf': '3'}}}}]
>>> for i in data[0]['x.x.x.x']['tcp']:
...     print i, data[0]['x.x.x.x']['tcp'][i]['product'], data[0]['x.x.x.x']['tcp'][i]['version']
... 
443 Apache Tomcat/Coyote JSP engine 1.1
80  
>>> 

You could use method items ( iteritems in Python 2) for extracting both port number and associated information:

In [4]: for port, info in data[0]['x.x.x.x']['tcp'].items():
   ...:     print(port, info['product'], info['version'])
   ...:   
443 Apache Tomcat/Coyote JSP engine 1.1
80  

You can always use d.keys() to see what is in the dictionary keys to traverse it.

    d = your dictionary

    d['x.x.x.x']['tcp']['443']['product']
    Out[109]: 'Apache Tomcat/Coyote JSP engine'

    d['x.x.x.x']['tcp']['443']['version']
    Out[110]: '1.1'

    d['x.x.x.x']['tcp']['80']['product']
    Out[109]: ''

    d['x.x.x.x']['tcp']['80']['version']
    Out[110]: ''

Your data is basically a tree, so it can be traversed recursively with a function like this:

def parse_data(output, keys_wanted, values_wanted, data):
    for key, val in data.iteritems():
        if key in keys_wanted:
            output.update({key: {k: val[k] for k in values_wanted}})
        if isinstance(val, dict):
            parse_data(output, keys_wanted, values_wanted, val)

Use:

data = <your dict>
keys = ['443', '80']
vals = ['product', 'version']
out = {}
parse_data(out, keys, vals, data)

Output:

>>> print out
{'443': {'product': 'Apache Tomcat/Coyote JSP engine', 'version': '1.1'}, '80': {'product': '', 'version': ''}}

A benefit to this function is that it's general purpose -- if you want different keys and values just pass different lists in the parameters.

BTW, in your sample input, the dict is inside a list, but there's just one item, so I stripped off the list brackets for simplicity's sake. If your actual data is in a list with many other items, you'd of course want to call this function in an iteration loop.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM