ti-enxame.com

Analisando json e procurando através dele

Eu tenho esse codigo 

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

Como posso pesquisar por u'uri': u'http:?

16
BKovac

Como json.loads simplesmente retorna um dict, você pode usar os operadores que se aplicam 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:'

Editar: para dar uma ideia sobre como percorrer os dados, considere o seguinte exemplo:

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

Inspecionar a estrutura de dados jdata permitirá que você navegue conforme desejar. A chamada pprint que você já tem é um bom ponto de partida para isso.

Edit2: outra tentativa. Isso obtém o arquivo que você mencionou em uma lista de dicionários. Com isso, acho que você deve ser capaz de adaptá-lo às suas necessidades.

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

Para então "pesquisar através dele para u'uri': u'http:'" , faça algo assim:

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

ObjectPath é uma biblioteca que fornece capacidade de consultar estruturas JSON e aninhadas de dicts e listas. Por exemplo, você pode procurar por todos os atributos chamados "foo", independentemente de quão profundo eles estão usando $..foo

Enquanto a documentação se concentra na interface de linha de comando, você pode executar as consultas programaticamente usando os componentes internos do pacote Python. O exemplo abaixo assume que você já carregou os dados nas estruturas de dados do Python (dicts & lists). Se você está começando com um arquivo JSON ou string, você só precisa usar load ou loads do módulo 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)

Observe que ele simplesmente ignorou elementos que não tinham um atributo "foo", como o terceiro item da lista. Você também pode fazer consultas muito mais complexas, o que torna o ObjectPath acessível para estruturas profundamente aninhadas (por exemplo, encontrar onde x tem y que tem z: $.x.y.z). Eu o encaminho para o documentation e tutorial para mais informações.

15
Scott H

Parece que há um erro de digitação (falta de dois pontos) no JSON dict fornecido pelo jro.

A sintaxe correta seria: Jdata = json.load ('{"uri": "http:", "foo": "bar"}')

Isso esclareceu para mim quando se joga com o código.

1
PythonPadawan

Você pode usar jsonpipe se você só precisa da saída (e mais confortável com a linha de comando):

cat bookmarks.json | jsonpipe |grep uri
0
number5

Funções para pesquisar e imprimir dicts, como JSON. * Made in python 3

Procurar:

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

Impressão:

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