首页 > 解决方案 > 如何在 Python 中正确解包这个 json 响应以将我需要的数据放入 Pandas DataFrame?

问题描述

所以,我正在使用 Cisco Prime 基础设施的 API,而且我已经走到了尽头。我正在编写的脚本应该从其 getReport 操作中获取报告,对其进行解码(不确定这是否是正确的词),并将其放入 Pandas DataFrame 中。问题是,它周围有垃圾。这是响应 json 的示例:

{
  "mgmtResponse" : {
    "@requestUrl" : "https://localhost/webacs/api/v4/op/reportService/getReport?reportTitle=MyReport",
    "@responseType" : "operation",
    "@rootUrl" : "https://localhost/webacs/api/v4/op",
    "reportDataDTO" : [ {
      "childReports" : {
        "childReport" : [ ]
      },
      "dataRows" : {
        "dataRow" : [ {
          "entries" : {
            "entry" : [ {
              "attributeName" : "String value",
              "dataValue" : "String value",
              "displayName" : "String value"
            }, {
              "attributeName" : "Another string value",
              "dataValue" : "Another string value",
              "displayName" : "Another string value"
            } ]
          }
        }, {
          "entries" : {
            "entry" : [ {
              "attributeName" : "String value",
              "dataValue" : "String value",
              "displayName" : "String value"
            }, {
              "attributeName" : "Another string value",
              "dataValue" : "Another string value",
              "displayName" : "Another string value"
            } ]
          }
        } ]
      },
      "descriptorName" : "String value",
      "pageCount" : 15,
      "pageIndex" : 15,
      "reportDate" : "String value",
      "reportName" : "String value",
      "reportTitle" : "String value",
      "reportUrl" : "String value"
    } ]
  }
}

我希望我的脚本只使用嵌套在“dataRows”下的信息,但我不知道该怎么做。到目前为止,我有这个:

response = rq.get(url, auth=(cpi_user,cpi_password), verify=False, timeout = 300)
    print(response.status_code)

    if (response.status_code == rq.codes.ok):
        responseJSON = response.json()
        rogue_ap_flatten = json_normalize(responseJSON)
        print (rogue_ap_flatten)
        rogues = pd.DataFrame(rogue_ap_flatten)
        print(rogues.head(50))
        return rogues

我得到的回报是:

                               mgmtResponse.@requestUrl  ...                         mgmtResponse.reportDataDTO
    0  https://prime/webacs/api/v4/op/reportS...  ...  [{'childReports': {'childReport': []}, 'dataRo...

[1 rows x 4 columns]

我尝试仅使用请求中的 .text 方法,我尝试使用另一个 json 扁平化库 (json_flatten) 并选择排除某些键,并且我正在考虑以某种方式在 python 中使用 sed。它不需要为其他报告工作,只需要一个,所以我有一些余地来指定任何特定的键或诸如此类的东西。你们将如何解决这个问题?

标签: pythonjsonpandas

解决方案


我的假设是您想根据传入的值构建熊猫 DF。json.loads 可能会有所帮助,因为“object_hook”可用于提供自定义反序列化。

import pandas as pd
import numpy as np
import json


def filter_cols(element):
    # deal with each dataRow and build your the structure that will get into the data frame
    return {
        element['attributeName']: element['dataValue'],
    }



if __name__ == '__main__':
    # from api response
    # content = json.loads(response.text)

    # doing this because I have your data in a file
    with open("data.json", "r") as read_file:
        content = json.load(read_file)

    f = pd.DataFrame.from_dict(
        json.loads(json.dumps(content['mgmtResponse']['reportDataDTO'][0]['dataRows']), object_hook=filter_cols))

推荐阅读