2011-12-05 10 views
11

Ho questo codiceAnalisi JSON e la ricerca attraverso di essa

import json 
from pprint import pprint 
json_data=open('bookmarks.json') 
jdata = json.load(json_data) 
pprint (jdata) 
json_data.close() 

Come posso cercare attraverso di essa per u'uri': u'http:?

risposta

15

Come json.loads semplicemente restituisce un dizionario, è possibile utilizzare gli operatori che si applicano a dicts:

>>> jdata = json.load('{"uri": "http:", "foo", "bar"}') 
>>> 'uri' in jdata  # Check if 'uri' is in jdata's keys 
True 
>>> jdata['uri']   # Will return the value belonging to the key 'uri' 
u'http:' 

Edit: per dare un'idea riguardo alle modalità di scorrere i dati, si consideri il seguente esempio:

>>> import json 
>>> jdata = json.loads(open ('bookmarks.json').read()) 
>>> for c in jdata['children'][0]['children']: 
...  print 'Title: {}, URI: {}'.format(c.get('title', 'No title'), 
              c.get('uri', 'No uri')) 
... 
Title: Recently Bookmarked, URI: place:folder=BOOKMARKS_MENU(...) 
Title: Recent Tags, URI: place:sort=14&type=6&maxResults=10&queryType=1 
Title: , URI: No uri 
Title: Mozilla Firefox, URI: No uri 

L'ispezione della struttura dati jdata consentirà di navigare come desiderato. La chiamata pprint è già un buon punto di partenza per questo.

Edit2: un altro tentativo. Questo ottiene il file che hai citato in un elenco di dizionari. Con questo, penso che dovresti essere in grado di adattarlo alle tue esigenze.

>>> def build_structure(data, d=[]): 
...  if 'children' in data: 
...   for c in data['children']: 
...    d.append({'title': c.get('title', 'No title'), 
...          'uri': c.get('uri', None)}) 
...    build_structure(c, d) 
...  return d 
... 
>>> pprint.pprint(build_structure(jdata)) 
[{'title': u'Bookmarks Menu', 'uri': None}, 
{'title': u'Recently Bookmarked', 
    'uri': u'place:folder=BOOKMARKS_MENU&folder=UNFILED_BOOKMARKS&(...)'}, 
{'title': u'Recent Tags', 
    'uri': u'place:sort=14&type=6&maxResults=10&queryType=1'}, 
{'title': u'', 'uri': None}, 
{'title': u'Mozilla Firefox', 'uri': None}, 
{'title': u'Help and Tutorials', 
    'uri': u'http://www.mozilla.com/en-US/firefox/help/'}, 
(...) 
}] 

Per poi "la ricerca in esso per u'uri': u'http:'", fare qualcosa di simile:

for c in build_structure(jdata): 
    if c['uri'].startswith('http:'): 
     print 'Started with http' 
+0

It ", linea 3, in ValueError: nome campo lunghezza zero in formato quando provo ad avviare il secondo esempio – BKovac

+0

Questo è probabilmente correlato al layout dei segnalibri esportati ... Non conosco il formato, ma suppongo che faccia una chiave 'children' per ogni cartella o contenitore che hai nei tuoi segnalibri. Provalo ad esempio con 'for c in jdata ['children']:' invece di quanto sopra. Inoltre, nota che la funzione ''{}'. Format()' è nuova in Python 2.6 ... potresti avere una versione precedente. In tal caso, sostituire la riga con 'print 'Titolo:% s, URI:% s'% (c.get ('titolo', 'Nessun titolo'), c.get ('uri', 'No uri'))) '. – jro

+0

Ancora non funziona Ecco il file bookmakrs http://pastebin.com/uCtECvDi – BKovac

0

È possibile utilizzare jsonpipe se avete solo bisogno l'uscita (e più a suo agio con la riga di comando):

cat bookmarks.json | jsonpipe |grep uri 
+0

jsonpipe link sembra essere cambiato o rimosso –

+0

@SureshPrajapati riparato – number5

3

ObjectPath è una libreria che fornisce la capacità di interrogare JSON e strutture annidate o f dicts ed elenchi. Ad esempio, è possibile cercare tutti gli attributi denominati "pippo" indipendentemente da quanto siano profondi utilizzando $..foo.

Mentre la documentazione si concentra sull'interfaccia della riga di comando, è possibile eseguire le query a livello di codice utilizzando gli interni di Python del pacchetto. L'esempio seguente presuppone che i dati siano già stati caricati in strutture di dati Python (dicce liste &). Se stai iniziando con un file o una stringa JSON, devi prima utilizzare load o loads dal json module.

import objectpath 

data = [ 
    {'foo': 1, 'bar': 'a'}, 
    {'foo': 2, 'bar': 'b'}, 
    {'NoFooHere': 2, 'bar': 'c'}, 
    {'foo': 3, 'bar': 'd'}, 
] 

tree_obj = objectpath.Tree(data) 

tuple(tree_obj.execute('$..foo')) 
# returns: (1, 2, 3) 

Avviso che gli elementi che mancavano un attributo "foo", come ad esempio il terzo elemento della lista appena saltato. Puoi anche eseguire query molto più complesse, il che rende ObjectPath pratico per strutture profondamente annidate (ad esempio, per trovare dove x ha y che ha z: $.x.y.z). Vi rimando allo documentation e allo tutorial per ulteriori informazioni.

1

Sembra che ci sia un errore di battitura (due punti mancanti) nel dict JSON fornito da jro.

la sintassi corretta sarebbe: jdata = json.load ('{ "uri": "http:", "foo": "bar"}')

Questo riesce per me quando si gioca con il codice.

0

Funzioni per cercare e stampare dic, come JSON. * realizzato in Python 3

Ricerca:

def pretty_search(dict_or_list, key_to_search, search_for_first_only=False): 
    """ 
    Give it a dict or a list of dicts and a dict key (to get values of), 
    it will search through it and all containing dicts and arrays 
    for all values of dict key you gave, and will return you set of them 
    unless you wont specify search_for_first_only=True 

    :param dict_or_list: 
    :param key_to_search: 
    :param search_for_first_only: 
    :return: 
    """ 
    search_result = set() 
    if isinstance(dict_or_list, dict): 
     for key in dict_or_list: 
      key_value = dict_or_list[key] 
      if key == key_to_search: 
       if search_for_first_only: 
        return key_value 
       else: 
        search_result.add(key_value) 
      if isinstance(key_value, dict) or isinstance(key_value, list) or isinstance(key_value, set): 
       _search_result = pretty_search(key_value, key_to_search, search_for_first_only) 
       if _search_result and search_for_first_only: 
        return _search_result 
       elif _search_result: 
        for result in _search_result: 
         search_result.add(result) 
    elif isinstance(dict_or_list, list) or isinstance(dict_or_list, set): 
     for element in dict_or_list: 
      if isinstance(element, list) or isinstance(element, set) or isinstance(element, dict): 
       _search_result = pretty_search(element, key_to_search, search_result) 
       if _search_result and search_for_first_only: 
        return _search_result 
       elif _search_result: 
        for result in _search_result: 
         search_result.add(result) 
    return search_result if search_result else None 

Stampa:

def pretty_print(dict_or_list, print_spaces=0): 
    """ 
    Give it a dict key (to get values of), 
    it will return you a pretty for print version 
    of a dict or a list of dicts you gave. 

    :param dict_or_list: 
    :param print_spaces: 
    :return: 
    """ 
    pretty_text = "" 
    if isinstance(dict_or_list, dict): 
     for key in dict_or_list: 
      key_value = dict_or_list[key] 
      if isinstance(key_value, dict): 
       key_value = pretty_print(key_value, print_spaces + 1) 
       pretty_text += "\t" * print_spaces + "{}:\n{}\n".format(key, key_value) 
      elif isinstance(key_value, list) or isinstance(key_value, set): 
       pretty_text += "\t" * print_spaces + "{}:\n".format(key) 
       for element in key_value: 
        if isinstance(element, dict) or isinstance(element, list) or isinstance(element, set): 
         pretty_text += pretty_print(element, print_spaces + 1) 
        else: 
         pretty_text += "\t" * (print_spaces + 1) + "{}\n".format(element) 
      else: 
       pretty_text += "\t" * print_spaces + "{}: {}\n".format(key, key_value) 
    elif isinstance(dict_or_list, list) or isinstance(dict_or_list, set): 
     for element in dict_or_list: 
      if isinstance(element, dict) or isinstance(element, list) or isinstance(element, set): 
       pretty_text += pretty_print(element, print_spaces + 1) 
      else: 
       pretty_text += "\t" * print_spaces + "{}\n".format(element) 
    else: 
     pretty_text += str(dict_or_list) 
    if print_spaces == 0: 
     print(pretty_text) 
    return pretty_text