如何从嵌套JSON中提取特定键?

时间:2019-10-22 09:36:54

标签: python json

我正在尝试解析嵌套的JSON数据,但是很难从高度嵌套的数据中获取文本

resp = platform.get('/restapi/v1.0/account/~/call-log', params)
print ((resp.text()))

cursor = mydb.cursor()

json_obj = json.loads((resp.text()))
for result in json_obj["records"]:
    cursor.execute("INSERT INTO calldata (sessionID, startTime, fromName) VALUES (%s, %s, %s)",
                        (result["sessionId"], 
                         result["startTime"], 
                         result["from"]["name"]))

JSON输出

{
  "uri" : "https://platform.ringcentral.com/restapi/v1.0/account/123456/call-log?view=Simple&showBlocked=true&withRecording=false&dateFrom=2019-10-09T16:00:00.000Z&page=1&perPage=2",
  "records" : [ {
    "uri" : "https://platform.ringcentral.com/restapi/v1.0/account/123456/call-log/123456?view=Simple",
    "id" : "123456",
    "sessionId" : "123456",
    "startTime" : "2019-10-09T20:47:26.577Z",
    "duration" : 45,
    "type" : "Voice",
    "direction" : "Outbound",
    "action" : "VoIP Call",
    "result" : "Call connected",
    "to" : {
      "phoneNumber" : "123456"
    },
    "from" : {
      "name" : "Jane Doe",
      "phoneNumber" : "123456",
      "extensionId" : "123456"
    },
    "recording" : {
      "uri" : "https://platform.ringcentral.com/restapi/v1.0/account/123456/recording/123456",
      "id" : "123456",
      "type" : "Automatic",
      "contentUri" : "https://media.ringcentral.com/restapi/v1.0/account/123456/recording/581514130067/content"
    },
    "extension" : {
      "uri" : "https://platform.ringcentral.com/restapi/v1.0/account/123456/extension/1409182064",
      "id" : 123456
    }
  }, {
    "uri" : "https://platform.ringcentral.com/restapi/v1.0/account/123456/call-log/123456?view=Simple",
    "id" : "123456",
    "sessionId" : "123456",
    "startTime" : "2019-10-09T20:37:49.540Z",
    "duration" : 7,
    "type" : "Voice",
    "direction" : "Inbound",
    "action" : "Phone Call",
    "result" : "Missed",
    "to" : {
      "phoneNumber" : "123456"
    },
    "from" : {
      "name" : "Bob Smith",
      "phoneNumber" : "123456"
    }
  } ],
  "paging" : {
    "page" : 1,
    "perPage" : 2,
    "pageStart" : 0,
    "pageEnd" : 1
  },
  "navigation" : {
    "nextPage" : {
      "uri" : "https://platform.ringcentral.com/restapi/v1.0/account/123456/call-log?view=Simple&showBlocked=true&withRecording=false&dateFrom=2019-10-09T16:00:00.000Z&page=2&perPage=2"
    },
    "firstPage" : {
      "uri" : "https://platform.ringcentral.com/restapi/v1.0/account/123456/call-log?view=Simple&showBlocked=true&withRecording=false&dateFrom=2019-10-09T16:00:00.000Z&page=1&perPage=2"
    },
    "lastPage" : {
      "uri" : "https://platform.ringcentral.com/restapi/v1.0/account/123456/call-log?view=Simple&showBlocked=true&withRecording=false&dateFrom=2019-10-09T16:00:00.000Z&page=1&perPage=2"
    }
  }
}

我得到的错误是

  

(result["sessionId"], result["startTime"], result["result"], result["direction"], result["duration"], result["from"]["name"])) KeyError: 'name'

我正在尝试从“字典”中获取数据以及“记录”。

3 个答案:

答案 0 :(得分:1)

如您所见,JSON的结构如下:

{
    "uri": "",
    "records": [
        {
            [...]
            "from": {
                "name": ""
            }
        },
        {
            [...]
        }
    ]
}

因此,如果您想访问result["from"]["name"],则实际上并没有真正了解它。首先,您有records->然后是from->然后是name。而且记录是数组,因此您不会results['records']['from']['name']

如果您想解析JSON,则可以这样做:

# Reading JSON section
import json

json_dict = json.load(open("a.json", "r"))
# Iterating over records
for record in json_dict["records"]:
    print(record["from"]["name"])

输出:

$ python test.py                                                                                                        
Jane Doe
Bob Smith

答案 1 :(得分:0)

使用pandas.io.json.json_normalize

  • 这将为您提供json_obj中的所有内容
  • 为最上面的键创建一个数据框,但records不会被扩展
  • records创建一个包含顶级uri的数据框
  • 在两个数据帧上使用pd.merge
import pandas as pd
from pandas.io.json import json_normalize

df_top = json_normalize(json_obj)

# drop the unexpanded records column
df_top.drop(columns='records', inplace=True)

df_rec = json_normalize(data, 'records', ['uri'], meta_prefix='top')

df_merged = pd.merge(df_rec, df_top, left_on='topuri', right_on='uri')

# drop and rename columns
df_m.drop(columns='topuri', inplace=True)
df_m.rename(columns={'uri_x': 'records.uri', 'uri_y': 'top.uri'}, inplace=True)

# df_merged view
                                                                              records.uri      id sessionId                 startTime  duration   type direction      action          result to.phoneNumber  from.name from.phoneNumber from.extensionId                                                                  recording.uri recording.id recording.type                                                                      recording.contentUri                                                                      extension.uri  extension.id                                                                                                                                                                    top.uri  paging.page  paging.perPage  paging.pageStart  paging.pageEnd                                                                                                                                                    navigation.nextPage.uri                                                                                                                                                   navigation.firstPage.uri                                                                                                                                                    navigation.lastPage.uri
 https://platform.ringcentral.com/restapi/v1.0/account/123456/call-log/123456?view=Simple  123456    123456  2019-10-09T20:47:26.577Z        45  Voice  Outbound   VoIP Call  Call connected         123456   Jane Doe           123456           123456  https://platform.ringcentral.com/restapi/v1.0/account/123456/recording/123456       123456      Automatic  https://media.ringcentral.com/restapi/v1.0/account/123456/recording/581514130067/content  https://platform.ringcentral.com/restapi/v1.0/account/123456/extension/1409182064      123456.0  https://platform.ringcentral.com/restapi/v1.0/account/123456/call-log?view=Simple&showBlocked=true&withRecording=false&dateFrom=2019-10-09T16:00:00.000Z&page=1&perPage=2            1               2                 0               1  https://platform.ringcentral.com/restapi/v1.0/account/123456/call-log?view=Simple&showBlocked=true&withRecording=false&dateFrom=2019-10-09T16:00:00.000Z&page=2&perPage=2  https://platform.ringcentral.com/restapi/v1.0/account/123456/call-log?view=Simple&showBlocked=true&withRecording=false&dateFrom=2019-10-09T16:00:00.000Z&page=1&perPage=2  https://platform.ringcentral.com/restapi/v1.0/account/123456/call-log?view=Simple&showBlocked=true&withRecording=false&dateFrom=2019-10-09T16:00:00.000Z&page=1&perPage=2
 https://platform.ringcentral.com/restapi/v1.0/account/123456/call-log/123456?view=Simple  123456    123456  2019-10-09T20:37:49.540Z         7  Voice   Inbound  Phone Call          Missed         123456  Bob Smith           123456              NaN                                                                            NaN          NaN            NaN                                                                                       NaN                                                                                NaN           NaN  https://platform.ringcentral.com/restapi/v1.0/account/123456/call-log?view=Simple&showBlocked=true&withRecording=false&dateFrom=2019-10-09T16:00:00.000Z&page=1&perPage=2            1               2                 0               1  https://platform.ringcentral.com/restapi/v1.0/account/123456/call-log?view=Simple&showBlocked=true&withRecording=false&dateFrom=2019-10-09T16:00:00.000Z&page=2&perPage=2  https://platform.ringcentral.com/restapi/v1.0/account/123456/call-log?view=Simple&showBlocked=true&withRecording=false&dateFrom=2019-10-09T16:00:00.000Z&page=1&perPage=2  https://platform.ringcentral.com/restapi/v1.0/account/123456/call-log?view=Simple&showBlocked=true&withRecording=false&dateFrom=2019-10-09T16:00:00.000Z&page=1&perPage=2
  • uri_x是记录中的uri,并重命名为records.uri
  • uri_ytopuri都是最高级别uri,它们被排除在合并之外
    • 拖放topuri并将uri_y重命名为top.uri
  • 根据需要拖放或重命名其他任何列,或仅使用所需列创建单独的数据框
  • 要保存,请使用df.to_csv或其他许多output options

注意:

  • 如果只希望recordsfrom在记录中),则只需要以下数据框df_rec = json_normalize(data, 'records'),就不需要合并。

答案 2 :(得分:-1)

看看您的json,我想说的问题是没有result["name"]键,但是有result["from"]["name"],请尝试使用它。