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