2011-12-05 33 views
11

tôi có mã nàyPhân tích json và tìm kiếm thông qua nó

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

Làm thế nào tôi có thể tìm kiếm thông qua nó cho u'uri': u'http:?

Trả lời

15

Như json.loads chỉ đơn giản là trả về một dict, bạn có thể sử dụng các toán tử áp dụng cho 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: để cung cấp cho một ý tưởng về làm thế nào để lặp qua các dữ liệu, hãy xem xét ví dụ sau:

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

Kiểm tra cấu trúc dữ liệu jdata sẽ cho phép bạn điều hướng nó theo ý muốn. Cuộc gọi pprint bạn đã có là điểm khởi đầu tốt cho việc này.

Chỉnh sửa2: Một lần thử khác. Điều này nhận được tệp bạn đã đề cập trong danh sách từ điển. Với điều này, tôi nghĩ rằng bạn sẽ có thể thích nghi nó với nhu cầu của bạn.

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

Để rồi "tìm kiếm thông qua nó cho u'uri': u'http:'", làm một cái gì đó như thế này:

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

", dòng 3, trong ValueError: không có tên trường có độ dài bằng định dạng khi tôi cố gắng bắt đầu ví dụ thứ hai – BKovac

+0

Điều đó có thể liên quan đến bố cục của các dấu trang bạn đã xuất ... Tôi thực sự không biết định dạng, nhưng tôi đoán nó sẽ tạo một khóa 'trẻ em' cho mỗi thư mục hoặc vùng chứa bạn có trong dấu trang của mình. Hãy thử ví dụ với 'for c trong jdata ['children']:' thay vì ở trên. Ngoài ra, lưu ý rằng hàm ''{}'. Format()' là mới trong Python 2.6 ... bạn có thể có một phiên bản cũ hơn. Nếu vậy, thay thế dòng đó bằng 'print 'Tiêu đề:% s, URI:% s'% (c.get ('title', 'No title'), c.get ('uri', 'No uri')) '. – jro

+0

Vẫn không hoạt động Dưới đây là tệp sổ sách http://pastebin.com/uCtECvDi – BKovac

0

Bạn có thể sử dụng jsonpipe nếu bạn chỉ cần đầu ra (và thoải mái hơn với dòng lệnh):

cat bookmarks.json | jsonpipe |grep uri 
+0

liên kết jsonpipe dường như được thay đổi hoặc xóa –

+0

@SureshPrajapati được sửa – number5

3

là thư viện cung cấp khả năng truy vấn JSON và cấu trúc lồng nhau o f dicts và danh sách. Ví dụ: bạn có thể tìm kiếm tất cả các thuộc tính được gọi là "foo" bất kể chúng sâu bao nhiêu bằng cách sử dụng $..foo.

Trong khi tài liệu tập trung vào giao diện dòng lệnh, bạn có thể thực hiện truy vấn theo chương trình bằng cách sử dụng nội bộ Python của gói. Ví dụ dưới đây giả định bạn đã tải dữ liệu vào cấu trúc dữ liệu Python (dicts & danh sách). Nếu bạn bắt đầu bằng một tệp JSON hoặc chuỗi, bạn chỉ cần sử dụng load hoặc loads từ số json module trước tiên.

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) 

Lưu ý rằng nó chỉ bỏ qua các phần tử thiếu thuộc tính "foo", chẳng hạn như mục thứ ba trong danh sách. Bạn cũng có thể thực hiện nhiều truy vấn phức tạp hơn, điều này làm cho ObjectPath tiện dụng cho các cấu trúc lồng nhau sâu sắc (ví dụ: tìm nơi x có y có z: $.x.y.z). Tôi giới thiệu bạn đến số documentationtutorial để biết thêm thông tin.

1

Dường như có lỗi đánh máy (thiếu dấu hai chấm) trong JSON dict do jro cung cấp.

Cú pháp đúng sẽ là: jdata = json.load ('{ "uri": "http:", "foo": "bar"}')

này xóa nó lên cho tôi khi chơi với mã.

0

Các chức năng tìm kiếm và in các dicts, như JSON. * thực hiện trong python 3

Tìm kiếm:

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 

In:

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 
Các vấn đề liên quan