web-dev-qa-db-fra.com

Analyser json et chercher à travers

J'ai ce code 

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

Comment puis-je chercher dans celui-ci pour u'uri': u'http:?

16
BKovac

Comme json.loads renvoie simplement un dict, vous pouvez utiliser les opérateurs qui s'appliquent aux 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: pour donner une idée de la façon de parcourir les données, considérons l'exemple suivant:

>>> 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'inspection de la structure de données jdata vous permettra de naviguer comme vous le souhaitez. L’appel pprint que vous avez déjà est un bon point de départ pour cela.

Edit2: Une autre tentative. Cela obtient le fichier que vous avez mentionné dans une liste de dictionnaires. Avec cela, je pense que vous devriez pouvoir l’adapter à vos besoins.

>>> 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/'},
 (...)
}]

Pour ensuite "chercher dans u'uri': u'http:'" , procédez comme ceci:

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

ObjectPath est une bibliothèque qui permet d'interroger JSON et les structures imbriquées de dessins et de listes. Par exemple, vous pouvez rechercher tous les attributs appelés "foo", quelle que soit leur profondeur, en utilisant $..foo

Bien que la documentation se concentre sur l'interface de ligne de commande, vous pouvez exécuter les requêtes par programme en utilisant les éléments internes Python du package. L'exemple ci-dessous suppose que vous avez déjà chargé les données dans des structures de données Python (dict et listes). Si vous commencez avec un fichier JSON ou une chaîne, vous devez simplement utiliser load ou loads à partir du module json first.

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)

Notez qu'il a simplement ignoré les éléments dépourvus de l'attribut "foo", comme le troisième élément de la liste. Vous pouvez également effectuer des requêtes beaucoup plus complexes, ce qui rend ObjectPath pratique pour les structures profondément imbriquées (par exemple, rechercher où x a y et qui a z: $.x.y.z). Je vous renvoie aux documentation et tutorial pour plus d'informations.

15
Scott H

On dirait qu'il y a une faute de frappe (deux points manquants) dans le dict JSON fourni par jro.

La syntaxe correcte serait: Jdata = json.load ('{"uri": "http:", "foo": "bar"}')

Cela m'a éclairci lorsque je jouais avec le code.

1
PythonPadawan

Vous pouvez utiliser jsonpipe si vous avez juste besoin du résultat (et plus à l'aise avec la ligne de commande):

cat bookmarks.json | jsonpipe |grep uri
0
number5

Fonctions de recherche et d’impression de dict, comme JSON . * Made in python 3

Chercher:

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

Impression:

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
0
Van4ozA