【问题标题】:JSON string parsing error in PythonPython中的JSON字符串解析错误
【发布时间】:2017-03-01 10:34:52
【问题描述】:

我正在向 API 发送一个请求,它会返回这个 JSON 响应

'{"Reply":{"Header":{"Method":"mGSSCBetHistory","ErrorCode": "0","MerchantID":"BETSTARtest","MessageID": "H140201152657m6k3f"},"Param":{"TotalRecord":"1","BetDatas":"[{"Column1":""}]","ErrorDesc": ""}}}'

当我尝试将其转换为字典时,无论是 ast.literal_eval 还是 json.loads,它都会返回此错误:

Traceback (most recent call last):
  File "/Users/deanchristianarmada/Desktop/projects/asian_gaming/radar/lib/python2.7/site-packages/celery/app/trace.py", line 367, in trace_task
    R = retval = fun(*args, **kwargs)
  File "/Users/deanchristianarmada/Desktop/projects/asian_gaming/radar/lib/python2.7/site-packages/celery/app/trace.py", line 622, in __protected_call__
    return self.run(*args, **kwargs)
  File "/Users/deanchristianarmada/Desktop/projects/asian_gaming/radar/provider/KENO/tasks.py", line 127, in run
    ['Reply', 'Param', 'BetDatas'], 'post')
  File "/Users/deanchristianarmada/Desktop/projects/asian_gaming/radar/core/classes.py", line 217, in check_records
    self.result = response.json()
  File "/Users/deanchristianarmada/Desktop/projects/asian_gaming/radar/lib/python2.7/site-packages/requests/models.py", line 826, in json
    return complexjson.loads(self.text, **kwargs)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/__init__.py", line 338, in loads
    return _default_decoder.decode(s)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/decoder.py", line 366, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/decoder.py", line 382, in raw_decode
    obj, end = self.scan_once(s, idx)
ValueError: Expecting ',' delimiter: line 1 column 169 (char 168)

这是因为 BetDatas 的值在双引号内有双引号。有没有简单的解决方法?因为我能想到的唯一合适的解决方案是告诉第三方我一直在发送请求以更改他们的 JSON 响应。

【问题讨论】:

  • 是的,它的 json 无效。

标签: python json django


【解决方案1】:

使用正则表达式匹配违规值,并使用re.sub 转义匹配项。

import re
import json

data = '{"Reply":{"Header":{"Method":"mGSSCBetHistory","ErrorCode": "0","MerchantID":"BETSTARtest","MessageID": "H140201152657m6k3f"},"Param":{"TotalRecord":"1","BetDatas":"[{"Column1":""}]","ErrorDesc": ""}}}'

def escape(match_obj):
    print(match_obj.group(1))
    return match_obj.group(1).replace('"','\"')
REGEX = '(?<="BetDatas":")(\S+)(?=",)'

data = re.sub(REGEX, escape, data)
print(data)

【讨论】:

  • 虽然这可能是一种解决方法,但更安全的解决方案是联系第三方并告诉他们他们返回的 JSON 无效。由于它们在此特定实例中不会转义特殊字符,因此它们可能不会在一般情况下这样做,可能需要您在未来添加更多的 hack。
  • @sxn 同意。一个新的请求很容易打破这个黑客
  • 哇,谢谢!我同意你的观点,我应该将此报告给第三方而不是进行黑客攻击
【解决方案2】:

如果您按照正确猜测排除“BetDatas”,那么它会正确解析

import json
json.loads('{"Reply":{"Header":{"Method":"mGSSCBetHistory","ErrorCode": "0","MerchantID":"BETSTARtest","MessageID": "H140201152657m6k3f"},"Param":{"TotalRecord":"1","ErrorDesc": ""}}}')

{u'Reply': {u'Header': {u'ErrorCode': u'0', u'MessageID': u'H140201152657m6k3f', u'Method': u'mGSSCBetHistory', u'MerchantID' : u'BETSTARtest'}, u'Param': {u'ErrorDesc': u'', u'TotalRecord': u'1'}}}

没有明显的方法来处理这个问题,这取决于 API 提供者纠正他们的 JSON。

【讨论】:

    猜你喜欢
    • 2013-05-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-29
    • 1970-01-01
    相关资源
    最近更新 更多