【问题标题】:How to deal with incorrect json format ? (simplejson.scanner.JSONDecodeError: Expecting value: line 1 column 1 (char 0))如何处理不正确的 json 格式? (simplejson.scanner.JSONDecodeError:期望值:第 1 行第 1 列(字符 0))
【发布时间】:2016-10-31 19:30:16
【问题描述】:

1) 几天前我工作了好几个星期的脚本坏了。我现在无法正确解析 JSON。所以这不是全新的代码,它已经运行了几个月。

2) 服务网站发生了一些变化,导致 JSON 不符合要求,但我一直试图规避这个问题,但没有成功。我想这可能是一个额外的空间或什么的,但我无法更改从服务网站返回的信息。

3) 我知道 json 不符合要求,因为我使用了验证器 (https://jsonformatter.curiousconcept.com/),将所需服务的 URL 与所需的凭据/格式放在一起,我得到了正确的结果,但验证失败并显示“无效编码,期待 UTF-8、UTF-16 或 UTF-32。[代码 29,结构 0]"。有一种方法可以告诉验证器不要验证,并且 Json 看起来是正确的,但 Python 不会与它有任何关系。当我运行我的脚本时,它会报告: simplejson.scanner.JSONDecodeError:预期值:第 1 行第 1 列(字符 0)。

4) 下面是我手动输入的 URL 和脚本。我已经混淆了所有敏感信息和个人信息,因此如果您尝试使用该 URL,则该 URL 将不起作用,但是当我使用非混淆格式时,我确实收到了 JSON 响应。

5) 手动 URL(经过混淆处理): https://mystuff.mydevices.com/Membership/SomeOtherURLrelated?appId=BB8pQgg123450WHahgl12345nAkkX67890q2HrHD7H1nabcde5KqtN654321LB%2fi&securityToken=null&username=myemail@somedomain.com&password=mypassword&culture=en

6) 如果我手动打开浏览器并输入之前的真实 URL(未修改),浏览器会以 json 响应。一个例子(混淆): {"UserId":0,"SecurityToken":"abcdb8c3-1ef1-1110-1234-402a914f52aa","ReturnCode":"0","ErrorMessage":"","BrandId":2,"BrandName":"Mydevicebrandname ","RegionId":1}

7) 我能做些什么来克服这个问题?有什么建议么 ?我一直在阅读和测试,但没有运气!

8) 现在脚本(经过混淆处理)基本上构建了先前的 URL 并从 JSON 中提取了一次性安全令牌,然后我可以在更大的应用程序中将其用于其他目的:

import json,requests


APPID    = 'BB8pQgg123450WHahgl12345nAkkX67890q2HrHD7H1nabcde5KqtN654321LB%2fi'
USERNAME = 'myemail@somedomain.com'
PASSWORD = 'mypassword'
CULTURE  = 'en'
SERVICE  = 'https://mystuff.mydevices.com'

def get_token_formydevices():   
    payload = {'appId': APPID,
               'securityToken': 'null',
               'username': USERNAME,
               'password': PASSWORD,
               'culture': CULTURE,}
    login_url = SERVICE + '/Membership/SomeOtherURLrelated'
    try:
        r = requests.get(login_url, params=payload)
    except requests.exceptions.RequestException as err:
        return       

    data = r.json()
    if data['ReturnCode'] != '0':
        print(data['ErrorMessage'])
        sys.exit(1)
    return data['SecurityToken']

tokenneeded = get_token_formydevices()

print tokenneeded

9) 当我运行之前的代码时,这就是我得到的结果:

Traceback (most recent call last):
  File "testtoken.py", line 33, in <module>
    tokenneeded = get_token_formydevices()
  File "testtoken.py", line 26, in get_token_formydevices
    data = r.json()
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/requests/models.py", line 826, in json
    return complexjson.loads(self.text, **kwargs)
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/simplejson/__init__.py", line 516, in loads
    return _default_decoder.decode(s)
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/simplejson/decoder.py", line 370, in decode
    obj, end = self.raw_decode(s)
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/simplejson/decoder.py", line 400, in raw_decode
    return self.scan_once(s, idx=_w(s, idx).end())
simplejson.scanner.JSONDecodeError: Expecting value: line 1 column 1 (char 0)

【问题讨论】:

  • 使用r.contentr.text 代替r.json(),这样您就可以准确地看到返回的内容。我猜它会是 HTML 或者什么都不是。如果它看起来像 JSON,请在此处发布您可以发布的内容。
  • 使用 r.content 或 r.text 我得到了这样的结果: $ python testtoken.py Request Rejected您的请求已被拒绝。

    [11679954572637177442]
  • 听起来您的凭据已过期。也许联系他们。
  • 我不确定情况是否如此。提供者不使用身份验证令牌,他们直接使用用户名/密码。当我手动将 URL 提交到我的网络浏览器时,我会收到一个 Json 响应。问题是我用来进行调用的 python 代码不正确,或者解析结果时出现问题(似乎是前者)。可能是我的问题是我所做的调用是错误的,但是直接遵循供应商的 API 并复制他们的代码 sn-p 并按预期修改不同的属性会提供相同的结果(请求已被拒绝)。

标签: python json python-2.7


【解决方案1】:

我找到了解决方案并想分享。

所以我对我可以在网络浏览器中打开服务 URL 并获取一些 json 的事实感到非常困惑,但我无法在我的脚本中执行此操作,甚至无法仅使用 cURL。即使请求从浏览器工作,我仍然不断收到“请求被拒绝”,所以它必须是别的东西。

所以我开始试验并在我的脚本中发送请求用户代理信息,瞧!尽管我混淆了原始 URL 和我的保护凭据,但下面的代码仍然有效。

我还想进一步说明,我这样做是因为服务 URL 提供了一个一次性令牌,然后我可以使用它来触发另一个操作。所以我需要这个例程和执行多次我需要进行特定操作,所以我想要的只是从该 url 的 json 表单中检索令牌。希望现在使用下面的代码更有意义。

import json,urllib2
url='https://mystuff.mydevices.com/Membership/SomeOtherURLrelated?appId=BB8pQgg123450WHahgl12345nAkkX67890q2HrHD7H1nabcde5KqtN654321LB%2fi&securityToken=null&username=myemail@somedomain.com&password=mypassword&culture=en'
request = urllib2.Request(url)
#request.add_header('User-Agent', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36')   # <--- this works too
request.add_header('User-Agent', 'Mozilla/5.0')
data = json.loads(str(urllib2.urlopen(request).read()))
token = data["SecurityToken"]
print token

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-06-16
    • 2017-05-09
    • 1970-01-01
    • 2013-05-10
    • 2019-02-25
    • 2023-03-25
    • 2018-06-28
    相关资源
    最近更新 更多