Tìm kiếm JSON của Python

JMESPath là một ngôn ngữ truy vấn JSON. JMESPath trong Python cho phép bạn lấy dữ liệu bạn cần từ tài liệu JSON hoặc từ điển một cách dễ dàng. Thư viện này có sẵn cho Python, nhưng cũng có sẵn cho nhiều ngôn ngữ lập trình khác, nghĩa là nếu bạn thành thạo ngôn ngữ truy vấn JMESPath, bạn có thể sử dụng nó ở nhiều nơi

Mục lục

Vấn đề JMESPath giải quyết

Như chúng ta đã thấy ở trang trước, thật dễ dàng để lấy giá trị lồng nhau từ từ điển Python bằng thư viện JSON của chính Python. Ví dụ.

>>> jmespath.search['persons[0]', persons]
{'name': 'erik', 'age': 38}
>>> jmespath.search['persons[0].age', persons]
38
1 sẽ cung cấp cho bạn giá trị lồng nhau của tuổi trong một tài liệu giống như thế này

{
  "persons": {
    "name": "erik",
    "age": "38"
  }
}

Nhưng nếu bạn muốn trích xuất tất cả các trường tuổi từ một mảng người, trong một tài liệu như bên dưới thì sao?

{
  "persons": [
    { "name": "erik", "age": 38 },
    { "name": "john", "age": 45 },
    { "name": "rob", "age": 14 }
  ]
}

Chúng ta có thể viết một vòng lặp for Python và lặp qua tất cả những người. Dễ như ăn bánh. Nhưng các vòng lặp chậm và gây phức tạp cho mã của bạn. Đây là nơi JMESPath phát huy tác dụng

Cài đặt JMESPath cho Python

JMESPath không phải là một phần của thư viện chuẩn Python, nghĩa là bạn sẽ cần cài đặt nó với pip hoặc pipenv. Gói JMESPath được lưu trữ trên PyPI, giống như hầu hết các gói Python. Nó có sẵn dưới cái tên không gây ngạc nhiên jmespath

Ví dụ: khi sử dụng pip trong môi trường ảo, bạn có thể cài đặt bằng pip và nhập mô-đun như sau

$ pip3 install jmespath
$ python3
Python 3.8.2 [default, Jul 16 2020, 14:00:26]
>>> import jmespath
>>> j = { "people": [{ "name": "erik", "age": 38 }] }
>>> jmespath.search["people[*].age", j]
[38]
>>>

Các ví dụ về JMESPath Python

Hãy bắt đầu với một số trường hợp sử dụng đơn giản. Chúng tôi sẽ lấy người đầu tiên từ mảng, sau đó lấy tuổi của người đầu tiên

>>> jmespath.search['persons[0]', persons]
{'name': 'erik', 'age': 38}
>>> jmespath.search['persons[0].age', persons]
38

Trong báo cáo vấn đề ở trên, chúng tôi muốn trích xuất tất cả các trường tuổi từ mảng người trong tài liệu JSON. Biểu thức JMESPath này sẽ hoàn thành công việc

>>> import jmespath
>>> persons = {
..   "persons": [
..     { "name": "erik", "age": 38 },
..     { "name": "john", "age": 45 },
..     { "name": "rob", "age": 14 }
..   ]
.. }
>>> jmespath.search['persons[*].age', persons]
[38, 45, 14]

Giả sử bạn muốn lọc danh sách và chỉ lấy độ tuổi của những người có tên 'erik'. Bạn có thể làm như vậy với một bộ lọc

>>> jmespath.search["persons[?name=='erik'].age", persons]
[38]

Lưu ý rằng chúng tôi hiện đang sử dụng dấu ngoặc kép vì chúng tôi cần trích dẫn tên bên trong biểu thức bộ lọc

Tất cả chúng ta đều là những người làm dữ liệu ở đây, vì vậy bạn đã biết kịch bản. Nó xảy ra 1 đến 100 lần mỗi ngày. Bạn bắt đầu làm việc với API REST mới và nó hoàn toàn phù hợp với nhu cầu của bạn. Thật dễ dàng để chuyển yêu cầu và phản hồi chứa tất cả thông tin bạn đang tìm kiếm

Tuy nhiên, chỉ có một vấn đề. sự phức tạp của các đối tượng JSON lồng nhau là vô tận, và đột nhiên công việc bạn yêu thích cần phải tạm dừng để truy xuất dữ liệu bạn muốn một cách tỉ mỉ, và đó là 5 cấp độ sâu trong địa ngục JSON lồng nhau. Không ai cảm thấy mình giống một "nhà khoa học" hay một "kỹ sư" khi nửa ngày của họ xử lý các lỗi giá trị quan trọng

May mắn thay, chúng tôi viết mã bằng Python. [được rồi, ngôn ngữ không tạo ra nhiều sự khác biệt ở đây. Nó giống như một cuộc gọi tập hợp vào thời điểm đó]

Sử dụng API Google Maps làm ví dụ

Để hình dung vấn đề, hãy lấy một ví dụ mà ai đó có thể muốn sử dụng. API Google Maps là một ứng cử viên sáng giá để phù hợp với hóa đơn tại đây

Mặc dù Google Maps là một tập hợp các API, nhưng Ma trận khoảng cách của Google Maps. Ý tưởng là với một lệnh gọi API duy nhất, người dùng có thể tính toán khoảng cách và thời gian di chuyển giữa điểm gốc và vô số điểm đến. Đó là một API đầy đủ tính năng tuyệt vời, nhưng như bạn có thể tưởng tượng, JSON kết quả để tính toán thời gian đi lại giữa nơi bạn đứng và mọi vị trí trong vũ trụ có thể hình dung được tạo nên một cấu trúc JSON cực kỳ phức tạp

Cảm nhận địa ngục JSON

Chúng tôi sẽ sử dụng API Google Maps để biết khoảng cách giữa hai địa điểm, cũng như thời gian ước tính để hoàn thành chuyến đi. Dưới đây chúng ta thấy một yêu cầu như vậy sẽ được thực hiện như thế nào thông qua thư viện yêu cầu của Python

Chúng ta cần truyền một số tham số

  • nguồn gốc. Địa điểm [hoặc địa điểm] đại diện cho nơi chuyến đi của chúng tôi bắt đầu. Giá trị này có thể được chuyển dưới dạng tên thành phố, địa chỉ hoặc các định dạng khác;
  • điểm đến. Tương đương với tham số
    {
      "destination_addresses": [
        "Philadelphia, PA, USA"
      ],
      "origin_addresses": [
        "New York, NY, USA"
      ],
      "rows": [{
        "elements": [{
          "distance": {
            "text": "94.6 mi",
            "value": 152193
          },
          "duration": {
            "text": "1 hour 44 mins",
            "value": 6227
          },
          "status": "OK"
        }]
      }],
      "status": "OK"
    }
    3 cho [các] điểm đến của chuyến đi
  • Chìa khóa. Khóa API của Google
  • transit_mode [Tùy chọn]. Phương thức vận chuyển cho chuyến đi [thông báo thời gian chuyến đi]
  • đơn vị [Tùy chọn]. Có trả về giá trị dưới dạng đơn vị
    {
      "destination_addresses": [
        "Philadelphia, PA, USA"
      ],
      "origin_addresses": [
        "New York, NY, USA"
      ],
      "rows": [{
        "elements": [{
          "distance": {
            "text": "94.6 mi",
            "value": 152193
          },
          "duration": {
            "text": "1 hour 44 mins",
            "value": 6227
          },
          "status": "OK"
        }]
      }],
      "status": "OK"
    }
    4 hoặc
    {
      "destination_addresses": [
        "Philadelphia, PA, USA"
      ],
      "origin_addresses": [
        "New York, NY, USA"
      ],
      "rows": [{
        "elements": [{
          "distance": {
            "text": "94.6 mi",
            "value": 152193
          },
          "duration": {
            "text": "1 hour 44 mins",
            "value": 6227
          },
          "status": "OK"
        }]
      }],
      "status": "OK"
    }
    5 hay không
"""Fetch and extract JSON data from Google Maps."""
import requests
from config import API_KEY


def google_maps_distance[]:
    """Fetch distance between two points."""
    endpoint = "//maps.googleapis.com/maps/api/distancematrix/json"
    params = {
       'units': 'imperial',
       'key': API_KEY,
       'origins': 'New York City, NY',
       'destinations': 'Philadelphia,PA',
       'transit_mode': 'car'
    }
    resp = requests.get[endpoint, params=params]
    return resp.json[]
Đưa ra một yêu cầu đơn giản tới Google Maps API

Vì chúng tôi đang xử lý một nguồn gốc và một đích duy nhất, phản hồi JSON kết quả cho yêu cầu này tương đối đơn giản

{
  "destination_addresses": [
    "Philadelphia, PA, USA"
  ],
  "origin_addresses": [
    "New York, NY, USA"
  ],
  "rows": [{
    "elements": [{
      "distance": {
        "text": "94.6 mi",
        "value": 152193
      },
      "duration": {
        "text": "1 hour 44 mins",
        "value": 6227
      },
      "status": "OK"
    }]
  }],
  "status": "OK"
}
Đầu ra của
{
  "destination_addresses": [
    "Philadelphia, PA, USA"
  ],
  "origin_addresses": [
    "New York, NY, USA"
  ],
  "rows": [{
    "elements": [{
      "distance": {
        "text": "94.6 mi",
        "value": 152193
      },
      "duration": {
        "text": "1 hour 44 mins",
        "value": 6227
      },
      "status": "OK"
    }]
  }],
  "status": "OK"
}
6

Đối với mỗi điểm đến, chúng tôi nhận được hai điểm dữ liệu. khoảng cách đi lại và thời lượng ước tính. Nếu theo giả thuyết chúng tôi muốn trích xuất các giá trị đó, thì việc nhập

{
  "destination_addresses": [
    "Philadelphia, PA, USA"
  ],
  "origin_addresses": [
    "New York, NY, USA"
  ],
  "rows": [{
    "elements": [{
      "distance": {
        "text": "94.6 mi",
        "value": 152193
      },
      "duration": {
        "text": "1 hour 44 mins",
        "value": 6227
      },
      "status": "OK"
    }]
  }],
  "status": "OK"
}
7 không quá điên rồ. Ý tôi là, nó hơi khủng khiếp và khiến người ta thường có ý nghĩ tự tử, nhưng không có gì khác thường cả.

Bây giờ, hãy làm cho mọi thứ trở nên thú vị bằng cách thêm một vài điểm dừng nữa trong chuyến đi của chúng ta

{
  "persons": [
    { "name": "erik", "age": 38 },
    { "name": "john", "age": 45 },
    { "name": "rob", "age": 14 }
  ]
}
3Đưa ra một yêu cầu phức tạp đối với Google Maps API

Ôi mẹ kiếp

{
  "persons": [
    { "name": "erik", "age": 38 },
    { "name": "john", "age": 45 },
    { "name": "rob", "age": 14 }
  ]
}
4Đầu ra của
{
  "destination_addresses": [
    "Philadelphia, PA, USA"
  ],
  "origin_addresses": [
    "New York, NY, USA"
  ],
  "rows": [{
    "elements": [{
      "distance": {
        "text": "94.6 mi",
        "value": 152193
      },
      "duration": {
        "text": "1 hour 44 mins",
        "value": 6227
      },
      "status": "OK"
    }]
  }],
  "status": "OK"
}
6

Rất nhiều điều đang xảy ra ở đây. Có những đối tượng. có danh sách. Có danh sách các đối tượng là một phần của đối tượng. Điều cuối cùng tôi muốn giải quyết là cố gắng phân tích dữ liệu này chỉ để vô tình nhận được một cặp khóa/giá trị vô dụng như "trạng thái". "VÂNG. "

Đoạn mã để giải cứu

Giả sử chúng ta chỉ muốn dữ liệu mà con người có thể đọc được từ JSON này, được gắn nhãn "văn bản" cho cả khoảng cách và thời lượng. Chúng tôi đã tạo một chức năng bên dưới có tên là

{
  "destination_addresses": [
    "Philadelphia, PA, USA"
  ],
  "origin_addresses": [
    "New York, NY, USA"
  ],
  "rows": [{
    "elements": [{
      "distance": {
        "text": "94.6 mi",
        "value": 152193
      },
      "duration": {
        "text": "1 hour 44 mins",
        "value": 6227
      },
      "status": "OK"
    }]
  }],
  "status": "OK"
}
9 để giúp giải quyết vấn đề này. Chức năng này được dự định là linh hoạt và bất khả tri, do đó có thể được nhập dưới dạng mô-đun vào bất kỳ dự án nào bạn có thể cần

{
  "persons": [
    { "name": "erik", "age": 38 },
    { "name": "john", "age": 45 },
    { "name": "rob", "age": 14 }
  ]
}
7trích xuất. py

Chúng ta cần truyền cho hàm này hai giá trị

  • Một từ điển Python phức tạp, chẳng hạn như phản hồi mà chúng tôi đã phân tích cú pháp từ
    {
      "persons": [
        { "name": "erik", "age": 38 },
        { "name": "john", "age": 45 },
        { "name": "rob", "age": 14 }
      ]
    }
    30
  • Tên của khóa từ điển chứa các giá trị chúng tôi muốn trích xuất
{
  "persons": [
    { "name": "erik", "age": 38 },
    { "name": "john", "age": 45 },
    { "name": "rob", "age": 14 }
  ]
}
9Đầu ra của
{
  "destination_addresses": [
    "Philadelphia, PA, USA"
  ],
  "origin_addresses": [
    "New York, NY, USA"
  ],
  "rows": [{
    "elements": [{
      "distance": {
        "text": "94.6 mi",
        "value": 152193
      },
      "duration": {
        "text": "1 hour 44 mins",
        "value": 6227
      },
      "status": "OK"
    }]
  }],
  "status": "OK"
}
9

Bất kể vị trí của khóa "văn bản" trong JSON, hàm này sẽ trả về mọi giá trị cho ví dụ về "khóa. " Đây là chức năng của chúng tôi trong hành động

$ pip3 install jmespath
$ python3
Python 3.8.2 [default, Jul 16 2020, 14:00:26]
>>> import jmespath
>>> j = { "people": [{ "name": "erik", "age": 38 }] }
>>> jmespath.search["people[*].age", j]
[38]
>>>
1chính. py

Chạy chức năng này sẽ dẫn đến đầu ra sau

$ pip3 install jmespath
$ python3
Python 3.8.2 [default, Jul 16 2020, 14:00:26]
>>> import jmespath
>>> j = { "people": [{ "name": "erik", "age": 38 }] }
>>> jmespath.search["people[*].age", j]
[38]
>>>
2Đầu ra của
{
  "destination_addresses": [
    "Philadelphia, PA, USA"
  ],
  "origin_addresses": [
    "New York, NY, USA"
  ],
  "rows": [{
    "elements": [{
      "distance": {
        "text": "94.6 mi",
        "value": 152193
      },
      "duration": {
        "text": "1 hour 44 mins",
        "value": 6227
      },
      "status": "OK"
    }]
  }],
  "status": "OK"
}
6

Oh  fiddle me woods. Bởi vì Google API luân phiên giữa khoảng cách và thời lượng chuyến đi, mọi giá trị khác luân phiên giữa khoảng cách và thời gian [chúng ta có thể tạm dừng để đánh giá cao thiết kế tồi tệ này không? Có vô số cách tốt hơn để cấu trúc phản hồi này]. Đừng sợ, một số Python đơn giản có thể giúp chúng tôi chia danh sách này thành hai danh sách

$ pip3 install jmespath
$ python3
Python 3.8.2 [default, Jul 16 2020, 14:00:26]
>>> import jmespath
>>> j = { "people": [{ "name": "erik", "age": 38 }] }
>>> jmespath.search["people[*].age", j]
[38]
>>>
4Phân tích mọi giá trị khác từ phản hồi JSON

Thao tác này sẽ lấy một danh sách của chúng ta và chia nó thành hai danh sách, xen kẽ giữa chẵn và lẻ

$ pip3 install jmespath
$ python3
Python 3.8.2 [default, Jul 16 2020, 14:00:26]
>>> import jmespath
>>> j = { "people": [{ "name": "erik", "age": 38 }] }
>>> jmespath.search["people[*].age", j]
[38]
>>>
5Đầu ra

Sáng tạo với danh sách

Một chủ đề phổ biến mà tôi gặp phải khi trích xuất danh sách giá trị từ các đối tượng JSON như thế này là danh sách giá trị tôi trích xuất có liên quan rất nhiều. Trong ví dụ trên, với mỗi khoảng thời gian, chúng ta có một khoảng cách đi kèm, đó là cơ sở một đối một. Hãy tưởng tượng nếu chúng ta muốn liên kết những giá trị này bằng cách nào đó

Để sử dụng một ví dụ tốt hơn, gần đây tôi đã sử dụng hàm

{
  "destination_addresses": [
    "Philadelphia, PA, USA"
  ],
  "origin_addresses": [
    "New York, NY, USA"
  ],
  "rows": [{
    "elements": [{
      "distance": {
        "text": "94.6 mi",
        "value": 152193
      },
      "duration": {
        "text": "1 hour 44 mins",
        "value": 6227
      },
      "status": "OK"
    }]
  }],
  "status": "OK"
}
9 của mình để tìm nạp danh sách tên cột và kiểu dữ liệu của chúng từ lược đồ cơ sở dữ liệu. Dưới dạng các danh sách riêng biệt, dữ liệu trông giống như thế này

{
  "destination_addresses": [
    "Philadelphia, PA, USA"
  ],
  "origin_addresses": [
    "New York, NY, USA"
  ],
  "rows": [{
    "elements": [{
      "distance": {
        "text": "94.6 mi",
        "value": 152193
      },
      "duration": {
        "text": "1 hour 44 mins",
        "value": 6227
      },
      "status": "OK"
    }]
  }],
  "status": "OK"
}
0Hai danh sách liên quan

Hai danh sách này có liên quan trực tiếp với nhau; . Làm thế nào điều này có thể hữu ích?

{
  "destination_addresses": [
    "Philadelphia, PA, USA"
  ],
  "origin_addresses": [
    "New York, NY, USA"
  ],
  "rows": [{
    "elements": [{
      "distance": {
        "text": "94.6 mi",
        "value": 152193
      },
      "duration": {
        "text": "1 hour 44 mins",
        "value": 6227
      },
      "status": "OK"
    }]
  }],
  "status": "OK"
}
1Nhép hai danh sách vào một từ điển

Tôi thích nghĩ rằng họ gọi nó là zip vì nó giống như kéo khóa kéo lên, trong đó mỗi bên của khóa kéo là một danh sách. Điều này xuất ra một từ điển trong đó danh sách 1 đóng vai trò là khóa và danh sách 2 đóng vai trò là giá trị

{
  "destination_addresses": [
    "Philadelphia, PA, USA"
  ],
  "origin_addresses": [
    "New York, NY, USA"
  ],
  "rows": [{
    "elements": [{
      "distance": {
        "text": "94.6 mi",
        "value": 152193
      },
      "duration": {
        "text": "1 hour 44 mins",
        "value": 6227
      },
      "status": "OK"
    }]
  }],
  "status": "OK"
}
2Danh sách nén dẫn đến từ điển

Và ở đó bạn có nó folks. một đoạn mã miễn phí để sao chép và bí mật giả vờ như bạn đã viết mãi mãi. Tôi đã đưa chức năng này lên Github Gists, nếu điều đó làm bạn hài lòng

Làm cách nào để tìm kiếm trong tệp JSON bằng Python?

Ví dụ-1. Khóa tìm kiếm trong dữ liệu JSON đơn giản . Giá trị của khóa sẽ được lấy làm đầu vào từ người dùng. Phương thức loading[] của mô-đun JSON được sử dụng để tải dữ liệu JSON trong biến có tên là khách hàng. Tiếp theo, toán tử 'in' được sử dụng để tìm khóa .

Làm cách nào để tìm kiếm một giá trị trong JSON?

Tìm kiếm giá trị trong mảng JSON .
Sử dụng các câu lệnh SELECT lồng nhau để làm rõ
Trích xuất mảng dự án
Chuyển đổi mảng thành một mảng riêng của các cặp khóa-giá trị bằng cách sử dụng CAST
Trích xuất từng phần tử mảng riêng lẻ bằng toán tử UNNEST
Lọc các giá trị thu được theo các dự án đã hoàn thành và đếm chúng

Làm cách nào để tìm một giá trị trong mảng JSON Python?

Làm cách nào để bạn đọc một mảng các đối tượng JSON trong Python? .
Nhập mô-đun json
dữ liệu mở. json bằng phương thức with[]
Tải đối tượng JSON bên trong dữ liệu. json bằng cách sử dụng json. phương thức tải []
In ra các giá trị của đối tượng JSON được trả về từ phương thức load[]

Làm cách nào để kiểm tra xem khóa có tồn tại trong JSON Python không?

Kiểm tra xem khóa có tồn tại hay không trong JSON . Ghi chú. Chúng tôi đã sử dụng json. loading[] để chuyển đổi dữ liệu được mã hóa JSON thành từ điển Python. Sau khi chuyển dữ liệu JSON thành từ điển, chúng ta có thể kiểm tra xem khóa có tồn tại hay không .

Chủ Đề