Разбор json и поиск по нему
у меня есть этот код
import json
from pprint import pprint
json_data=open('bookmarks.json')
jdata = json.load(json_data)
pprint (jdata)
json_data.close()
Как я могу искать через него для u'uri': u'http:
?
5 ответов
As json.loads
просто возвращает dict, вы можете использовать операторы, которые применяются к 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: чтобы дать представление о том, как перебирать данные, рассмотрим следующий пример:
>>> 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
проверка jdata
структура данных позволит вам перемещаться как угодно. The pprint
звонок у вас уже есть хорошая отправная точка для этого.
Edit2: еще одна попытка. Это возвращает файл, который вы упомянули в списке словарей. С это, я думаю, вы должны быть в состоянии адаптировать его к вашим потребностям.
>>> 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/'},
(...)
}]
затем "поиск по ней u'uri': u'http:'
", сделайте что-нибудь вроде этого:
for c in build_structure(jdata):
if c['uri'].startswith('http:'):
print 'Started with http'
ObjectPath - это библиотека, которая предоставляет возможность запрашивать JSON и вложенные структуры dicts и списков. Например, вы можете искать все атрибуты, называемые "foo", независимо от их глубины с помощью $..foo
.
в то время как документация фокусируется на интерфейсе командной строки, вы можете выполнять запросы программно, используя внутренние компоненты Python пакета. В приведенном ниже примере предполагается, что вы уже загрузили данные в структуры данных Python (словарь & включенный.) Если вы начинаете с файла JSON или строки, вам просто нужно использовать load
или loads
С модуль json первый.
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)
обратите внимание, что он просто пропустил элементы, которым не хватало атрибута "foo", например, третий элемент в списке. Вы также можете выполнять гораздо более сложные запросы, что делает ObjectPath удобным для глубоко вложенных структур (например, поиск, где x имеет y, который имеет z:$.x.y.z
). Я отсылаю вас к документация и учебник для получения дополнительной информации.
кажется, что в JSON dict, предоставленном jro, есть опечатка (отсутствует двоеточие).
правильный синтаксис будет: д ля настройки журналирования = формат JSON.load ('{"uri":" http:"," foo":"bar"}')
это прояснило его для меня, когда я играл с кодом.
функции для поиска и печати диктов, таких как JSON. * сделано в python 3
найти:
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
печати:
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
можно использовать jsonpipe Если вам просто нужен выход (и более удобный с командной строкой):
cat bookmarks.json | jsonpipe |grep uri