簡體   English   中英

如何從json中提取數據

[英]How can I extract data from json

我想從 JSON 格式中提取代碼。

import json
json_data = '''
    {
        "Body": {
            "stkCallback": {
                "MerchantRequestID": "22531-976234-1",
                "CheckoutRequestID": "ws_CO_DMZ_250600506_23022019144745852",
                "ResultCode": 0,
                "ResultDesc": "The service request is processed successfully.",
                "CallbackMetadata": {
                    "Item": [
                        {
                            "Name": "Amount",
                            "Value": 1.0
                        },
                        {
                            "Name": "MpesaReceiptNumber",
                            "Value": "NBN52K8A1J"
                        },
                        {
                            "Name": "Balance"
                        },
                        {
                            "Name": "TransactionDate",
                            "Value": 20190223144807
                        },
                        {
                            "Name": "PhoneNumber",
                            "Value": 254725696042
                        }
                    ]
                }
            }
        }
    }
'''

json_da = data['Body']
list_data = data['Body']['MpesaReceiptNumber']
print (json_da)
print (list_data)

我想打印這個: NBN52K8A1J

問題是您有一個需要先搜索的dict列表:

>>> for obj in data['Body']['stkCallback']['CallbackMetadata']['Item']:
...   print(obj)
...
{'Name': 'Amount', 'Value': 1.0}
{'Name': 'MpesaReceiptNumber', 'Value': 'NBN52K8A1J'}
{'Name': 'Balance'}
{'Name': 'TransactionDate', 'Value': 20190223144807}
{'Name': 'PhoneNumber', 'Value': 254725696042}

一種可能性是

>>> [x['Value'] for x in data['Body']['stkCallback']['CallbackMetadata']['Item'] if x['Name'] == 'MpesaReceiptNumber'][0]
'NBN52K8A1J'

只需使用庫 json。 然后你可以打印它的內部元素

導入json

json_data = '{"Body":{"stkCallback":{"MerchantRequestID":"22531-976234-1","CheckoutRequestID":"ws_CO_DMZ_250600506_23022019144745852","ResultCode":0,"ResultDesc":"The service request is processed successfully.","CallbackMetadata":{"Item":[{"Name":"Amount","Value":1.00},{"Name":"MpesaReceiptNumber","Value":"NBN52K8A1J"},{"Name":"Balance"},{"Name":"TransactionDate","Value":20190223144807},{"Name":"PhoneNumber","Value":254725696042}]}}}}'
a = json.loads(json_data)
print(a["Body"]["stkCallback"]["CallbackMetadata"]["Item"][1]["Value"])

如果您解析 json,您會注意到數據的路徑不是簡單的 ['Body']['MpesaReceiptNumber']。 事實上,您在 ['Item'] 中有一個需要搜索的字典列表。

解析數據樹

一種建議是運行以下代碼來查找您要查找的數據:

import json
json_data = '{"Body":{"stkCallback":{"MerchantRequestID":"22531-976234-1","CheckoutRequestID":"ws_CO_DMZ_250600506_23022019144745852","ResultCode":0,"ResultDesc":"The service request is processed successfully.","CallbackMetadata":{"Item":[{"Name":"Amount","Value":1.00},{"Name":"MpesaReceiptNumber","Value":"NBN52K8A1J"},{"Name":"Balance"},{"Name":"TransactionDate","Value":20190223144807},{"Name":"PhoneNumber","Value":254725696042}]}}}}'
data = (json.loads(json_data))

list_data = data['Body']['stkCallback']['CallbackMetadata']['Item']

# Returns:
# [{'Name': 'Amount', 'Value': 1.0}, {'Name': 'MpesaReceiptNumber', 'Value':'NBN52K8A1J'}, {'Name': 'Balance'}, {'Name': 'TransactionDate', 'Value': 20190223144807}, {'Name': 'PhoneNumber', 'Value': 254725696042}]

# Now find Name: 'MpesaReceiptNumber' inside the dict list
find_it = next(item for item in list_data if item["Name"] == "MpesaReceiptNumber")
find_it = find_it['Value']

print (find_it)

結果

NBN52K8A1J

您幾乎可以從字典中獲取鍵值對本身並檢查它是否是您想要的名稱:

data = json.loads(json_data)
list_data = data['Body']["stkCallback"]['CallbackMetadata']['Item']
var: str

for x in list_data:
    if x['Name'] == 'MpesaReceiptNumber':
       var = x['Value']
       break

print(var)

您可以在將來輕松使用它,方法是將 if 檢查替換為其他名稱,以便您可以根據變量獲取值。

我發現使用 pprint 獲取數據結構的形狀在您學習如何完全導航時很有幫助。

import json
import pprint

json_data = '{"Body":{"stkCallback":{"MerchantRequestID":"22531-976234-1","CheckoutRequestID":"ws_CO_DMZ_250600506_23022019144745852","ResultCode":0,"ResultDesc":"The service request is processed successfully.","CallbackMetadata":{"Item":[{"Name":"Amount","Value":1.00},{"Name":"MpesaReceiptNumber","Value":"NBN52K8A1J"},{"Name":"Balance"},{"Name":"TransactionDate","Value":20190223144807},{"Name":"PhoneNumber","Value":254725696042}]}}}}'
data = json.loads(json_data)

pprint.pprint(data)

結果是:

{'Body': {'stkCallback': {'CallbackMetadata': {'Item': [{'Name': 'Amount', 'Value': 1.0},
                                                        {'Name': 'MpesaReceiptNumber', 'Value': 'NBN52K8A1J'},
                                                        {'Name': 'Balance'},
                                                        {'Name': 'TransactionDate', 'Value': 20190223144807},
                                                        {'Name': 'PhoneNumber', 'Value': 254725696042}]},
                          'CheckoutRequestID': 'ws_CO_DMZ_250600506_23022019144745852',
                          'MerchantRequestID': '22531-976234-1',
                          'ResultCode': 0,
                          'ResultDesc': 'The service request is processed successfully.'}}}

因此,您應該能夠看到data["Body"]["stkCallback"]["CallbackMetadata"]["Item"]達到您的數據所需的深度。

 >>> pprint.pprint(data["Body"]["stkCallback"]["CallbackMetadata"]["Item"])

 [{'Name': 'Amount', 'Value': 1.0},
 {'Name': 'MpesaReceiptNumber', 'Value': 'NBN52K8A1J'},
 {'Name': 'Balance'},
 {'Name': 'TransactionDate', 'Value': 20190223144807},
 {'Name': 'PhoneNumber', 'Value': 254725696042}]

因此接下來您需要遍歷該列表並找到MpesaReceiptNumber鍵的匹配項(如果存在)。

receipt_no = None
for item in data["Body"]["stkCallback"]["CallbackMetadata"]["Item"]:
    if item.get('Name') == 'MpesaReceiptNumber':
        receipt_no = item.get('Value')

print(f"The receipt # is: {receipt_no}")

使用jq

首先,它可以“漂亮地打印”任何 JSON 數據。

json_data的值放入文件test.json ,然后顯示 JSON 數據的格式化輸出:

$ jq <test.json
{
  "Body": {
    "stkCallback": {
      "MerchantRequestID": "22531-976234-1",
      "CheckoutRequestID": "ws_CO_DMZ_250600506_23022019144745852",
      "ResultCode": 0,
      "ResultDesc": "The service request is processed successfully.",
      "CallbackMetadata": {
        "Item": [
          {
            "Name": "Amount",
            "Value": 1
          },
          {
            "Name": "MpesaReceiptNumber",
            "Value": "NBN52K8A1J"
          },
          {
            "Name": "Balance"
          },
          {
            "Name": "TransactionDate",
            "Value": 20190223144807
          },
          {
            "Name": "PhoneNumber",
            "Value": 254725696042
          }
        ]
      }
    }
  }
}

接下來,要提取值,需要在jq命令行上給出選擇器路徑:

jq '.Body.stkCallback.CallbackMetadata.Item|.[]|select(.Name == "MpesaReceiptNumber")|.Value' test.json
"NBN52K8A1J"

現在為了使這個序列更容易理解,讓我們逐個分解它。

僅提取和返回.Body

$ jq '.Body' <test.json
{
  "stkCallback": {
    "MerchantRequestID": "22531-976234-1",
    "CheckoutRequestID": "ws_CO_DMZ_250600506_23022019144745852",
    "ResultCode": 0,
    "ResultDesc": "The service request is processed successfully.",
    "CallbackMetadata": {
      "Item": [
        {
          "Name": "Amount",
          "Value": 1
        },
        {
          "Name": "MpesaReceiptNumber",
          "Value": "NBN52K8A1J"
        },
        {
          "Name": "Balance"
        },
        {
          "Name": "TransactionDate",
          "Value": 20190223144807
        },
        {
          "Name": "PhoneNumber",
          "Value": 254725696042
        }
      ]
    }
  }
}

現在讓我們獲取stkCallback組件:

$ jq '.Body.stkCallback' <test.json
{
  "MerchantRequestID": "22531-976234-1",
  "CheckoutRequestID": "ws_CO_DMZ_250600506_23022019144745852",
  "ResultCode": 0,
  "ResultDesc": "The service request is processed successfully.",
  "CallbackMetadata": {
    "Item": [
      {
        "Name": "Amount",
        "Value": 1
      },
      {
        "Name": "MpesaReceiptNumber",
        "Value": "NBN52K8A1J"
      },
      {
        "Name": "Balance"
      },
      {
        "Name": "TransactionDate",
        "Value": 20190223144807
      },
      {
        "Name": "PhoneNumber",
        "Value": 254725696042
      }
    ]
  }
}

好的,現在callbackMetadata

$ jq '.Body.stkCallback.CallbackMetadata' <test.json
{
  "Item": [
    {
      "Name": "Amount",
      "Value": 1
    },
    {
      "Name": "MpesaReceiptNumber",
      "Value": "NBN52K8A1J"
    },
    {
      "Name": "Balance"
    },
    {
      "Name": "TransactionDate",
      "Value": 20190223144807
    },
    {
      "Name": "PhoneNumber",
      "Value": 254725696042
    }
  ]
}

接下來, Item部分:

$ jq '.Body.stkCallback.CallbackMetadata.Item' <test.json
[
  {
    "Name": "Amount",
    "Value": 1
  },
  {
    "Name": "MpesaReceiptNumber",
    "Value": "NBN52K8A1J"
  },
  {
    "Name": "Balance"
  },
  {
    "Name": "TransactionDate",
    "Value": 20190223144807
  },
  {
    "Name": "PhoneNumber",
    "Value": 254725696042
  }
]

請注意,結果是一個列表項數組 讓我們數組中過濾數據:

$ jq '.Body.stkCallback.CallbackMetadata.Item|.[]' <test.json
{
  "Name": "Amount",
  "Value": 1
}
{
  "Name": "MpesaReceiptNumber",
  "Value": "NBN52K8A1J"
}
{
  "Name": "Balance"
}
{
  "Name": "TransactionDate",
  "Value": 20190223144807
}
{
  "Name": "PhoneNumber",
  "Value": 254725696042
}

現在結果只是元組列表,每個元組都有一個“名稱”和“值”。 所以,讓我們只選擇一個我們(你)想要的:

$ jq '.Body.stkCallback.CallbackMetadata.Item|.[]|select(.Name == "MpesaReceiptNumber")' <test.json
{
  "Name": "MpesaReceiptNumber",
  "Value": "NBN52K8A1J"
}

涼爽的。 我們得到了我們想要的元組。 讓我們現在只提取值:

$ jq '.Body.stkCallback.CallbackMetadata.Item|.[]|select(.Name == "MpesaReceiptNumber")|.Value' <test.json
"NBN52K8A1J"

而且,你去。

獲取與特定CallbackMetadata項名稱關聯的值的最簡單方法:

json_string = '''
    {
        "Body": {
            "stkCallback": {
               ...
    }
'''

json_data = json.loads(json_string)

for item in json_data["Body"]["stkCallback"]["CallbackMetadata"]["Item"]:
    if item["Name"] == "MpesaReceiptNumber":
        print(item["Value"])  # -> NBN52K8A1J

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM