为了账号安全,请及时绑定邮箱和手机立即绑定

从不完整的 HTTP JSON 响应中完成一个 json 字符串

从不完整的 HTTP JSON 响应中完成一个 json 字符串

三国纷争 2021-09-28 15:15:34
有时我会从 json api 下载数据,它中途切断,通常是由于网络超时或其他一些问题。但是,在这种情况下,我希望能够读取可用数据。下面是一个例子:{    "response": 200,    "message": None,    "params": []    "body": {        "timestamp": 1546033192,        "_d": [                {"id": "FMfcgxwBTsWRDsWDqgqRtZlLMdpCpTDz"},                {"id": "FMfcgxwBTkFSKqRrcKzMFvLCjDSSbrJH"},                {"id": "Fmfgo9我希望能够“完成字符串”,以便我能够将不完整的响应解析为 json。例如:s = '''{    "response": 200,    "message": null,    "params": [],    "body": {        "timestamp": 1546033192,        "_d": [                {"id": "FMfcgxwBTsWRDsWDqgqRtZlLMdpCpTDz"},                {"id": "FMfcgxwBTkFSKqRrcKzMFvLCjDSSbrJH"}              ]    }}'''json.loads(s){'response': 200, 'message': None, 'params': [], 'body': {'timestamp': 1546033192, '_d': [{'id': 'FMfcgxwBTsWRDsWDqgqRtZlLMdpCpTDz'}, {'id': 'FMfcgxwBTkFSKqRrcKzMFvLCjDSSbrJH'}]}}我如何能够使用任意构造的 json 对象(如上述)执行上述操作?
查看完整描述

2 回答

?
慕尼黑的夜晚无繁华

TA贡献1864条经验 获得超6个赞

为这个任务编写解析器的想法在智力上真的很有趣,但我强烈警告你不要遵循这种方法。

根本问题是,当网络请求失败时,您将进入未定义行为的领域。你绝对不能保证你的结果输出会是什么,所以你可能不应该尝试修改一个。

这两种可能性要么是您的输入不完整但部分可理解,要么是完全不可理解。增加的复杂性与失败的网络请求的未定义性质相结合意味着您可能不应该尝试定义它。

TCP/IP 协议如何处理类似问题为例。对于网络,经常会出现数据包丢失,这意味着部分数据无法完全传输。引用维基百科的话说,TCP“检测数据包丢失并执行重传以确保可靠的消息传递”。

我强烈建议采用类似的方法。要么重新获取数据,要么简单地将错误视为福音,并对错误状态进行处理。


查看完整回答
反对 回复 2021-09-28
?
慕码人2483693

TA贡献1860条经验 获得超9个赞

这是我这样做的方式,构建一堆}和]字符来尝试“完成”。它有点冗长,可以清理,但它适用于我尝试过的一些字符串输入:


s='''{

"response": 200,

"message": null,

"params": [],

"body": {

    "timestamp": 1546033192,

    "_d": [

            {"id": "FMfcgxwBTsWRDsWDqgqRtZlLMdpCpTDz"},

            {"id": "FMfcgxwBTkFSKqRrcKzMFvLCjDSSbrJH"},

            {"id": "Fmfgo9'''


>>> f.complete_json_structure(s)

{'response': 200, 'message': None, 'params': [], 'body': {'timestamp': 1546033192, '_d': [{'id': 'FMfcgxwBTsWRDsWDqgqRtZlLMdpCpTDz'}, {'id': 'FMfcgxwBTkFSKqRrcKzMFvLCjDSSbrJH'}]}}

这是代码:


# Build the 'unfinished character' stack

unfinished = []

for char in file_data:

    if char in ['{', '[']:

        unfinished.append(char)

    elif char in ['}', ']']:

        inverse_char = '{' if char == '}' else '['

        # Remove the last one

        unfinished.reverse()

        unfinished.remove(inverse_char)

        unfinished.reverse()


# Build the 'closing occurrence string' 

unfinished.reverse()

unfinished = ['}' if (char == '{') else ']' for char in unfinished]

unfinished_str = ''.join(unfinished)


# Do a while loop to try and parse the json

data = None

while True:


    if not json_string:

        raise FileParserError("Could not parse the JSON file or infer its format.")


    if json_string[-1] in ('}', ']'):


        try:

            data = json.loads(json_string + unfinished_str)

        except json.decoder.JSONDecodeError:

            # do it a second time as a sort of hack to fix the "trailing comma issue" (or could do a remove last comma, but that gets tricky)

            try:

                data = json.loads(json_string + unfinished_str[1:])

            except json.decoder.JSONDecodeError:

                pass


        if data is not None:

            break


    if json_string[-1] == unfinished_str[0]:

        unfinished_str = unfinished_str[1:]


    json_string = json_string[:-1].strip().rstrip(',')


return data



查看完整回答
反对 回复 2021-09-28
  • 2 回答
  • 0 关注
  • 194 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号