python 提取复杂 json 的数据

python 提取复杂 json 的数据,第1张

前言

在越来越多的项目中,基本都用了 json 作为接口数据返回的格式。


json 给我们的感觉就是通俗易懂,只是即使再复杂的结构也会比其他格式容易看。


然而一旦在调试或者测试中需要用到提取某一部分字段数据进行解析并校验的话,就没那么容易了。


这篇文章使用 python 简单地获取到复杂 json 数据中的字段信息。


例子

如果有一个接口返回的 json 信息如下:

{
  "familyName": "thinker family",
  "homeTown": "广东省",
  "formed": 2016,
  "secretBase": "Super city",
  "active": true,
  "familyMembers": [
    {
      "name": "Jobs",
      "age": 35,
      "secretIdentity": "1992238132345",
      "powers": [
        "Radiation resistance",
        "Turning tiny",
        "Radiation blast"
      ]
    },
    {
      "name": "James",
      "age": 37,
      "secretIdentity": "8839394098124",
      "powers": [
        "Million tonne punch",
        "Damage resistance",
        "Superhuman reflexes"
      ]
    }
  ]
}

这里就包含了对象,以及列表数据。


对象中也包含列表数据。


这应该是最基本的企业接口 json 格式了。



假如你要提取 json 中的 name 信息,最简单的方式就是

member = [ members.get('name') for members in data.get('familyMembers') ]

如果是要连续拿其他的信息,那么就需要换其他中获取方式,其实这种是比较麻烦的一种方法。


解决方法
extract_element_from_json(data, ["familyMembers", "name"])
>> ['Jobs', 'James']

此函数根据 path 中指定的键嵌套到obj中的记录中以检索所需的信息。


当遇到一个列表作为 path 中键的值时,此函数会拆分并以深度优先的方式继续嵌套在遇到的列表的每个元素上。


这就是返回 ['Jobs', 'James'] 的方式;因为 familyMembers 的值是一个列表,所以嵌套在它的两个元素上被拆分,并且 name 的每个值都附加到输出列表中。



如果 obj 是单个字典/ json,则此函数返回包含所需信息的列表,如果 obj 是字典/ json 列表,则此函数返回包含所需信息的双重列表。



如果嵌套字典/ json 的相应级别缺少 path 的元素,则此函数返回 [None]



完整代码如下:

def extract_element_from_json(obj, path):
    '''
    输入关键字,就可以将关键字的值信息存放在列表中并输出
    如果关键字是对象名,则返回的对象字典信息到列表中
    如果关键字是列表名,则返回的列表信息到列表中(返回双重列表)
    '''
    def extract(obj, path, ind, arr):
    	'''
    	从一个嵌套的字典中提取一个元素,并返回到列表中。


params: obj - dict - 输入字典 params: path - list - 构成JSON路径的字符串列表 params: ind - int - 起始索引 params: arr - 列表 - 输出列表 ''' key = path[ind] if ind + 1 < len(path): if isinstance(obj, dict): if key in obj.keys(): extract(obj.get(key), path, ind + 1, arr) else: arr.append(None) elif isinstance(obj, list): if not obj: arr.append(None) else: for item in obj: extract(item, path, ind, arr) else: arr.append(None) if ind + 1 == len(path): if isinstance(obj, list): if not obj: arr.append(None) else: for item in obj: arr.append(item.get(key, None)) elif isinstance(obj, dict): arr.append(obj.get(key, None)) else: arr.append(None) return arr if isinstance(obj, dict): return extract(obj, path, 0, []) elif isinstance(obj, list): outer_arr = [] for item in obj: outer_arr.append(extract(item, path, 0, [])) return outer_arr

​这段代码可以直接复制使用。



其中使用方法很简单如下:

extract_element_from_json(data, ["familyMembers", "name"])
api 提取元素
import requests

url = "http://ip-api.com/json"

response = requests.request("GET", url)

data = response.json()

extract_element_from_json(data, ["status"])

就是这么简单地使用了。


应用场景

通过这样的方式可以在什么场景下使用呢?

  1. 接口重构,需要校验接口中的部分字段数据
  2. 接口新增字段,只针对新增的字段进行提取校验
  3. 需要提取某一部分字段进行数据传递

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/langs/570938.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-04-09
下一篇2022-04-09

发表评论

登录后才能评论

评论列表(0条)

    保存