解析 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 个回答
1
看起来jro提供的JSON字典里有个错别字(缺少冒号)。
正确的写法应该是:
jdata = json.load('{"uri": "http:", "foo": "bar"}')
当我在玩这个代码的时候,这个问题就解决了。
35
ObjectPath 是一个库,它可以帮助你查询 JSON 数据以及嵌套的字典和列表结构。比如,你可以用 $..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,y 中有 z 的情况:$.x.y.z
)。如果想了解更多信息,可以参考 文档 和 教程。
29
因为 json.loads
只是返回一个字典,所以你可以使用适用于字典的操作符:
>>> 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:'
补充一下:为了让你了解如何遍历数据,可以参考下面的例子:
>>> 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
这个数据结构,可以让你根据自己的需要进行导航。你已经有的 pprint
调用是一个很好的起点。
补充2:这是另一个尝试。这个方法可以把你提到的文件转成一个字典列表。这样的话,我觉得你应该能根据自己的需求进行调整。
>>> 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'