python解析复杂的json

897 阅读3分钟

这是我参与8月更文挑战的第30天,活动详情查看:8月更文挑战

我们在接口测试,还是python开发的过程中,都会遇到复杂json的解析的,但是怎么去解析这些复杂的json呢。其实也是一个技术活,用jsonpath是可以,但是有的时候,我们又不能取用jsonpath来解析,那么这个时候怎么办,怎么去解决这个问题呢,其实答案还是很简单的,怎么解决呢,那就是自己去封装一个方法去解析这个json呢。

那么我的思路是什么的,首先呢,我们是要解析复杂的json,我们先把json加载下,变成复杂的dict,变成dict,我们知道每个dict都是有key-value形式构成,那么我们去解析每一个key的value,我们拿到value去判断value是否可以再次拆解撑key-value格式的,然后在继续去读取这个复杂的value。层层去抓取,用递归的方式去解决这个问题。最后去把取到的和预期的值去增加到一个list里面,最后去解析这个value就可以,那么我们看看代码是怎么实现的。

def get_dict_value(d, co_de):
    result = []
    if isinstance(d, dict):
        try:
            value = d[co_de]
            result.append(value)
        except Exception as e:
            pass
        for valuedd in d.values():
            if isinstance(valuedd, dict):
                yied_result = getdictvalue(valuedd, co_de)
                if len(yied_result) != 0:
                    result.append(getdictvalue(valuedd, co_de))
            elif isinstance(valuedd, (list, tuple)):
                for item in d:
                    valueitem = getdictvalue(item, co_de)
                    if valueitem != "None" and valueitem is not None and len(valueitem) != 0:
                        if valueitem not in result:
                            result.append(valueitem)
            elif isinstance(valuedd,str):
                try:
                    resultd = eval(valuedd)
                    for item in resultd:
                        value = getdictvalue(item, co_de)
                        if value != "None" and value is not None and len(value) != 0:
                            if value not in result:
                                result.append(value)
                except:
                    pass
        gc.collect()

    elif isinstance(d, (list, tuple)):
        for item in d:
            value = get_dict_value(item, co_de)
            if value != "None" and value is not None and len(value) != 0:
                if value not in result:
                    result.append(value)
        gc.collect()
    else:
        try:
            d=eval(d)
            for item in d:
                value = get_dict_value(item, co_de)
                if value != "None" and value is not None and len(value) != 0:
                    if value not in result:
                        result.append(value)
            gc.collect()
        except:
            pass
    return result

解析后,返回了一个复杂的list,我们需要对这个复杂的list做处理。怎么处理呢,思路就是把层层返回的list迭代读取出来,组成新的list即可。


class listchangetype(object):
    """对于查找后的list的数据的清洗"""

    def __init__(self):
        self.arg = []

    def make(self, listone):
        for i in listone:
            if isinstance(i, (type, list)):
                for l in i:
                    self.make(i)
            else:
                if i not in self.arg:
                    self.arg.append(i)
        gc.collect()
        return self.arg

这样,我们就封装好了一个解析复杂json的,我们可以去试试,找一个json串。这里我省略了json.loads()这个步骤。直接去读取转换后的dict,我们看下结果

dicttwo={'code': 0, 'msg': 'success'}
print(getdictvalue(dicttwo,"msg"))

运行结果:

image.png 有人说你这个是简单的dict,复杂的怎么办,我们在来试试。


dicttwo={'code': 0, 'msg': 'success', 'errors': None, 'data': [{'id': 0,},{"id":1}]}
print(getdictvalue(dicttwo,"id"))

返回结果:

image.png 这个就是我们要封装上面list解析的原因,每次迭代返回的格式不一样。


listone=listchangetype()
dicttwo={'code': 0, 'msg': 'success', 'errors': None, 'data': [{'id': 0,},{"id":1}]}
result=getdictvalue(dicttwo,"id")
print(listone.make(result))

结果:

image.png 这样,我们就简单了封装了一个复杂的json的解析。