首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用Python将纯文本API响应解析为JSON

使用Python将纯文本API响应解析为JSON
EN

Stack Overflow用户
提问于 2022-03-18 03:45:29
回答 1查看 279关注 0票数 0

用于项目的API端点返回表单的纯文本响应:

代码语言:javascript
复制
[RESPONSE]
code = 200
description = Command completed successfully
queuetime = 0
runtime = 0.071
property[abuse policy][0] = The policies are published at the REGISTRY_OPERATOR website at:
property[abuse policy][1] = =>https://registry.in/Policies 
property[abuse policy][2] = 
property[abuse policy][3] = IN Policy Framework: https://registry.in/system/files/inpolicy_0.pdf
property[abuse policy][4] = IN Domain Anti-Abuse policy: https://registry.in/Policies/IN_Anti_Abuse_Policy
property[abuse policy url][0] = https://registry.in/Policies/IN_Anti_Abuse_Policy
property[active][0] = 0

我正在尝试使用Python将其解析为字典。目前,我有以下代码:

代码语言:javascript
复制
import re
def text_to_dict(text):
    js = {}
    for s in text.splitlines():
        x = s.split("=", maxsplit=1)
        if len(x) > 1:
            keys = [k for i in re.split("\]|\[", x[0]) if (k := i.strip())]
            for i, k in enumerate(keys):
                pd = js
                for j,pk in enumerate(keys[:i]):
                    if keys[j+1:j+2] and not (keys[j+1:j+2][0]).isnumeric():
                        pd = pd[pk]
                if k not in pd:
                    if k.isnumeric():
                        pd[keys[i-1]].append((x[1]).strip())
                    else:
                        pd[k] = (x[1]).strip() if i == len(keys)-1 else [] if keys[i+1:i+2] and (keys[i+1:i+2][0]).isnumeric() else {}
    return js

此代码可以处理上面的示例,并返回:

代码语言:javascript
复制
{
    "code": "200",
    "description": "Command completed successfully",
    "runtime": "0.081",
    "queuetime": "0",
    "property": {
        "abuse policy": [
            "The policies are published at the REGISTRY_OPERATOR website at:",
            "=>https://registry.in/Policies",
            "",
            "IN Policy Framework: https://registry.in/system/files/inpolicy_0.pdf",
            "IN Domain Anti-Abuse policy: https://registry.in/Policies/IN_Anti_Abuse_Policy"
        ],
        "abuse policy url": [
            "https://registry.in/Policies/IN_Anti_Abuse_Policy"
        ],
        "active": [
            "0"
        ]
    }
}

但是,如果我将其附加到上面的示例中,则无法处理以下问题:

代码语言:javascript
复制
...
property[active][1][test] = TEST

代码语言:javascript
复制
...
property[active][1][0] = TEST

哪一个应该回来

代码语言:javascript
复制
{
    ...
    "active": [
            "0",
            {"test": "TEST"}
        ]
}

代码语言:javascript
复制
{
    ...
    "active": [
            "0",
            ["TEST"]
        ]
}

分别使用。

我觉得有一种更简单的方法来解释所有的可能性,而不需要编写一堆嵌套的ifs,但我不知道是什么。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-03-18 05:49:27

您的输入数据实际上是INI文件格式。为了方便起见,Python使用了configparser模块。

当我们假定密钥'property[foo][0][test]'的每一部分实际上都是一个dict (没有嵌套列表)时,我们会将其解析为这个结构:

代码语言:javascript
复制
{'property': {'foo': {'0': {'test': 'value'}}}}

这可以通过一个循环来完成,该循环一直在创建嵌套的dicts:

代码语言:javascript
复制
from configparser import ConfigParser

def parse(text):
    config = ConfigParser()
    config.read_string(text)

    root = {}
    for key in config['RESPONSE'].keys():
        curr = root
        for key_part in key.replace(']', '').split('['):
            if key_part not in curr:
                curr[key_part] = {}
            prev = curr
            curr = curr[key_part]
        prev[key_part] = config['RESPONSE'][key]
    return root

用法

代码语言:javascript
复制
from pprint import pprint

text = """
[RESPONSE]
code = 200
description = Command completed successfully
queuetime = 0
runtime = 0.071
property[abuse policy][0] = The policies are published at the REGISTRY_OPERATOR website at:
property[abuse policy][1] = =>https://registry.in/Policies 
property[abuse policy][2] = 
property[abuse policy][3] = IN Policy Framework: https://registry.in/system/files/inpolicy_0.pdf
property[abuse policy][4] = IN Domain Anti-Abuse policy: https://registry.in/Policies/IN_Anti_Abuse_Policy
property[abuse policy url][0] = https://registry.in/Policies/IN_Anti_Abuse_Policy
property[active][0] = 0
property[foo][0][test] = a
property[foo][1][test] = b
property[bar][0][0] = A
property[bar][1][1] = B
"""

pprint(parse(text))

结果

代码语言:javascript
复制
{'code': '200',
 'description': 'Command completed successfully',
 'property': {'abuse policy': {'0': 'The policies are published at the '
                                    'REGISTRY_OPERATOR website at:',
                               '1': '=>https://registry.in/Policies',
                               '2': '',
                               '3': 'IN Policy Framework: '
                                    'https://registry.in/system/files/inpolicy_0.pdf',
                               '4': 'IN Domain Anti-Abuse policy: '
                                    'https://registry.in/Policies/IN_Anti_Abuse_Policy'},
              'abuse policy url': {'0': 'https://registry.in/Policies/IN_Anti_Abuse_Policy'},
              'active': {'0': '0'},
              'bar': {'0': {'0': 'A'}, '1': {'1': 'B'}},
              'foo': {'0': {'test': 'a'}, '1': {'test': 'b'}}},
 'queuetime': '0',
 'runtime': '0.071'}

您可以检查key_part是否是数字的,并将其转换为int,以便生成的结构更像包含的列表。

代码语言:javascript
复制
{'property': {'foo': {0: {'test': 'value'}}}}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71522248

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档