2014-03-19 4 views
0

У меня возникли проблемы получить мою голову вокруг этой структуры данных Python:Iterate Python структура данных

data = {'nmap': {'command_line': u'ls', 
        'scaninfo': {u'tcp': {'method': u'connect', 
             'services': u'80,443'}}, 
        'scanstats': {'downhosts': u'0', 
           'elapsed': u'1.18', 
           'timestr': u'Wed Mar 19 21:37:54 2014', 
           'totalhosts': u'1', 
           'uphosts': u'1'}}, 
     'scan': {u'url': {'addresses': {u'ipv6': u'2001:470:0:63::2'}, 
             'hostname': u'abc.net', 
             'status': {'reason': u'syn-ack', 
                'state': u'up'}, 
             u'tcp': {80: {'conf': u'3', 
                 'cpe': '', 
                 'extrainfo': '', 
                 'name': u'http', 
                 'product': '', 
                 'reason': u'syn-ack', 
                 'state': u'open', 
                 'version': ''}, 
               443: {'conf': u'3', 
                 'cpe': '', 
                 'extrainfo': '', 
                 'name': u'https', 
                 'product': '', 
                 'reason': u'syn-ack', 
                 'script': { 
                  u'ssl-cert': u'place holder'}, 
                 'state': u'open', 
                 'version': ''}}, 
             'vendor': {} 
     } 
     } 
} 

В принципе мне нужно перебрать «ТСР» ключевые ценности и извлекать содержимое «сценария» пункт если он существует.

Это то, что я пробовал:

items = data["scan"] 
for item in items['url']['tcp']: 
    if t["script"] is not None: 
     print t 

Однако я не могу заставить его работать.

+0

Вы перепутали 'item' и' t' btw. – poke

ответ

1

Найдет любые словарные элементы с ключом 'script' где-нибудь в структуре данных:

def find_key(data, search_key, out=None): 
    """Find all values from a nested dictionary for a given key.""" 
    if out is None: 
     out = [] 
    if isinstance(data, dict): 
     if search_key in data: 
      out.append(data[search_key]) 
     for key in data: 
      find_key(data[key], search_key, out) 
    return out 

Для данных, я получаю:

>>> find_key(data, 'script') 
[{'ssl-cert': 'place holder'}] 

Чтобы найти порты, слишком , слегка изменить:

tcp_dicts = find_key(data, 'tcp') # find all values for key 'tcp' 
ports = [] # list to hold ports 
for d in tcp_dicts: # iterate through values for key 'tcp' 
    if all(isinstance(port, int) for port in d): # ensure all are port numbers 
     for port in d: 
      ports.append((port, 
          d[port].get('script'))) # extract number and script 

Теперь вы получаете что-то вроде:

[(80, None), (443, {'ssl-cert': 'place holder'})] 
+0

Отлично! Спасибо, что помогли здесь. – user1513388

+0

Ещё один вопрос здесь. Если бы я хотел включить порты «tcp», то есть 80 и 443 в выходные данные, как я мог это сделать? – user1513388

+0

Я отредактировал мой вопрос, чтобы ответить на это – jonrsharpe

0

Вы хотите сказать if item["script"]?

Действительно, если ключ имеет шанс не существовать, используйте метод get, предоставленный dict.

Так попробуйте вместо

items = data["scan"] 
for item in items['url']['tcp']: 
    script = item.get('script') 
    if script: 
     print script 
1

data['scan']['url']['tcp'] является словарем, поэтому, когда вы просто итерацию над ней, вы получите ключи но не значения. Если вы хотите перебрать значения, вы должны сделать так:

for t in data['scan']['url']['tcp'].values(): 
    if 'script' in t and t['script'] is not None: 
     print(t) 

Если вам нужен ключ, а также, итерацию по элементам вместо:

for k, t in data['scan']['url']['tcp'].items(): 
    if 'script' in t and t['script'] is not None: 
     print(k, t) 

Вы также должны изменить свой тест сначала проверить 'script' in t, в противном случае доступ к t['script'] вызовет ключевую ошибку.

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