JSONDecodeError:预期值:第1行第1列(字符0)


258

Expecting value: line 1 column 1 (char 0)尝试解码JSON 时出现错误。

我用于API调用的URL在浏览器中可以正常工作,但是通过curl请求完成时会出现此错误。以下是我用于curl请求的代码。

错误发生在 return simplejson.loads(response_json)

    response_json = self.web_fetch(url)
    response_json = response_json.decode('utf-8')
    return json.loads(response_json)


def web_fetch(self, url):
        buffer = StringIO()
        curl = pycurl.Curl()
        curl.setopt(curl.URL, url)
        curl.setopt(curl.TIMEOUT, self.timeout)
        curl.setopt(curl.WRITEFUNCTION, buffer.write)
        curl.perform()
        curl.close()
        response = buffer.getvalue().strip()
        return response

完整回溯:

追溯:

File "/Users/nab/Desktop/myenv2/lib/python2.7/site-packages/django/core/handlers/base.py" in get_response
  111.                         response = callback(request, *callback_args, **callback_kwargs)
File "/Users/nab/Desktop/pricestore/pricemodels/views.py" in view_category
  620.     apicall=api.API().search_parts(category_id= str(categoryofpart.api_id), manufacturer = manufacturer, filter = filters, start=(catpage-1)*20, limit=20, sort_by='[["mpn","asc"]]')
File "/Users/nab/Desktop/pricestore/pricemodels/api.py" in search_parts
  176.         return simplejson.loads(response_json)
File "/Users/nab/Desktop/myenv2/lib/python2.7/site-packages/simplejson/__init__.py" in loads
  455.         return _default_decoder.decode(s)
File "/Users/nab/Desktop/myenv2/lib/python2.7/site-packages/simplejson/decoder.py" in decode
  374.         obj, end = self.raw_decode(s)
File "/Users/nab/Desktop/myenv2/lib/python2.7/site-packages/simplejson/decoder.py" in raw_decode
  393.         return self.scan_once(s, idx=_w(s, idx).end())

Exception Type: JSONDecodeError at /pricemodels/2/dir/
Exception Value: Expecting value: line 1 column 1 (char 0)

2
最后但并非最不重要的一点是,print repr(response_json)告诉您什么被传递给了.loads()
马丁·彼得斯

4
还有一点:为什么simplejson只使用stdlib json与相同的库simplejson)时为什么要使用?
马丁·彼得斯

3
那是一个空字符串。您的web_fetch() 通话失败。
马丁·彼得斯

1
是的,我建议您使用比起来更容易使用的东西pycurlrequests提供了更简单的API,尤其是在调试正在发生的事情时。除非特别需要simplejson库的更新版本,否则只要坚持使用json,就可以节省要管理的依赖项。
马丁·彼得斯

1
response_json的返回值.json()?然后,您已经解码了数据,不需要使用json.loads()了。response为您解码。
马丁·彼得斯

Answers:


123

总结评论中的对话:

  • 无需使用simplejson库,Python作为json模块包含了相同的库。

  • 无需解码UTF8对unicode的响应,simplejson/ json .loads()方法可以本地处理UTF8编码的数据。

  • pycurl有一个非常古老的API。除非您有特定的使用要求,否则会有更好的选择。

requests提供最友好的API,包括JSON支持。如果可以,将您的通话替换为:

import requests

return requests.get(url).json()

93
我正在使用requests!痕迹似乎暗示requests使用complexjson,其中使用simplejson。奇怪的。
rayu 2016年

@Rayu:将使用simplejson请求(如果有);有些人想使用最新的simplejson版本,而不是与Python stdlib捆绑在一起的版本。
马丁·彼得斯

5
“无需使用simplejson库,Python包含与json模块相同的库。” ...我谨不同意。simplejson使用json引擎盖下的内置功能,但给出了更多的描述性错误。在这种情况下,使用json只会给您一个泛型ValueError: No JSON object could be decoded
BoltzmannBrain

2
这可能是由json异常终止或不完整引起的吗?我偶尔会随机得到它,不确定如何重现它。
克里斯托弗·罗西

2
@ChristopheRoussy:是的,这才是问题的关键(OP得到了空的 u''答复)。您JSONDecodeError告诉您很多数据已成功解析,然后才出错。这可能是因为该时间点存在无效数据(JSON文档格式错误或已损坏)或由于数据被截断了。
马丁·彼得斯

64

检查响应数据主体,是否存在实际数据并且数据转储的格式是否正确。

在大多数情况下,您的json.loads- JSONDecodeError: Expecting value: line 1 column 1 (char 0)错误是由于:

  • 非JSON引用
  • XML / HTML输出(即以<开头的字符串),或
  • 不兼容的字符编码

最终,错误告诉您字符串在第一位置已经不符合JSON。

这样,如果尽管乍一看具有看起来像JSON的数据主体,但解析仍然失败,请尝试替换数据主体的引号:

import sys, json
struct = {}
try:
  try: #try parsing to dict
    dataform = str(response_json).strip("'<>() ").replace('\'', '\"')
    struct = json.loads(dataform)
  except:
    print repr(resonse_json)
    print sys.exc_info()

注意:数据中的引号必须正确转义


4
在评论中很明显,OP得到了空洞的回应。由于requests.get(url).json()Just Works,JSON也不会格式错误。
马丁·彼得斯

JSONDecodeError: Expecting value: line 1 column 1 (char 0)特别是在将空字符串传递给json解码时发生
wesinat0r

JSONDecodeError: Expecting value: line 1 column 1 (char 0)当json响应的第一行无效时也会发生。运行az cli命令的示例响应为["WARNING: The default kind for created storage account will change to 'StorageV2' from 'Storage' in the future", '{',。这给了我导致我出现此错误的错误。其余的响应是有效的json对象。只是第一行破坏了事情。
SeaDude

34

当您有一个HTTP错误代码(例如404)并尝试将响应解析为JSON时,使用requestslib JSONDecodeError可能会发生!

您必须首先检查200(OK)或让它出现错误以避免这种情况。我希望它以较少的错误消息失败。

注意:就像注释中提到的Martijn Pieters一样,如果发生错误(取决于实现),服务器可以使用JSON进行响应,因此检查Content-Type标头更加可靠。


抱歉,您的旧评论还是可以链接到示例?我正在尝试将自己的技能从“执行动作”变为“尝试执行动作,返回响应并做出相应反应”。
dcclassics

@dcclassics:示例:它在服务器端失败,服务器通过显示错误页面(HTML)而不是用JSON进行响应,因此解析答案的代码将尝试读取JSON,但在HTML标记上将失败。
Christophe Roussy

1
服务器可以并且确实在错误响应中包含JSON主体。这不仅是200 OK响应。您要检查Content-Type标头。
马丁·彼得斯

29

我认为值得一提的是,在您解析JSON文件本身的内容时-健全性检查对于确保您实际上在调用文件json.loads()内容(而不是该JSON 的文件路径)非常有用。:

json_file_path = "/path/to/example.json"

with open(json_file_path, 'r') as j:
     contents = json.loads(j.read())

我有些尴尬地承认有时会发生这种情况:

contents = json.loads(json_file_path)

好吧..有时候确实会发生。谢谢它的工作顺便说一句。
萨钦·库马尔

我认为在这种情况下,应该使用json.load()
Coddy

13

检查文件的编码格式,并在读取文件时使用相应的编码格式。它将解决您的问题。

with open("AB.json", encoding='utf-8', errors='ignore') as json_data:
     data = json.load(json_data, strict=False)

3
encoding='utf-8'只需进行一点点更改,这对我就起作用了,所以我想有时您需要尝试一些方法。
RobertMyles

9

很多时候,这是因为您要解析的字符串为空:

>>> import json
>>> x = json.loads("")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/Cellar/python/3.7.3/Frameworks/Python.framework/Versions/3.7/lib/python3.7/json/__init__.py", line 348, in loads
    return _default_decoder.decode(s)
  File "/usr/local/Cellar/python/3.7.3/Frameworks/Python.framework/Versions/3.7/lib/python3.7/json/decoder.py", line 337, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "/usr/local/Cellar/python/3.7.3/Frameworks/Python.framework/Versions/3.7/lib/python3.7/json/decoder.py", line 355, in raw_decode
    raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)

您可以通过json_string事先检查是否为空来进行补救:

import json

if json_string:
    x = json.loads(json_string)
else:
    // Your logic here
    x = {}

在我的代码中进一步调试时,我正在调用response.read(),然后当另一个调用导致发生此类情况时感到沮丧Expecting value: line 1。删除了调试语句并解决了问题。

要进行调试,您还可以使用这个不错的网站jsonlint.com
Roelant

4

即使调用了decode(),也可能嵌入了0。使用replace():

import json
struct = {}
try:
    response_json = response_json.decode('utf-8').replace('\0', '')
    struct = json.loads(response_json)
except:
    print('bad json: ', response_json)
return struct

2

使用请求,我遇到了这个问题。感谢Christophe Roussy的解释。

为了调试,我使用了:

response = requests.get(url)
logger.info(type(response))

我从API返回了404响应。


1
可以简化为response.status_codeprint(response.status_code)
TitanFighter

1

我在请求(python库)时遇到了同样的问题。它恰好是accept-encoding标题。

它是这样设置的: 'accept-encoding': 'gzip, deflate, br'

我只是将其从请求中删除,并停止获取错误。


1

对我来说,它没有在请求中使用身份验证。


1

对我来说,这是服务器响应而不是200响应,并且响应不是json格式的。我最终在json解析之前执行了此操作:

# this is the https request for data in json format
response_json = requests.get() 

# only proceed if I have a 200 response which is saved in status_code
if (response_json.status_code == 200):  
     response = response_json.json() #converting from json to dictionary using json library

这是我的问题。状态码是500(内部服务器错误),而不是200,因此没有返回json,因此json的第1行第1行没有任何内容。检查请求状态代码是否符合您的期望总是很不错的。
thposs

0

如果您是Windows用户,则Tweepy API可以在数据对象之间生成一个空行。由于这种情况,您会收到“ JSONDecodeError:预期值:第1行第1列(字符0)”错误。为避免此错误,您可以删除空行。

例如:

 def on_data(self, data):
        try:
            with open('sentiment.json', 'a', newline='\n') as f:
                f.write(data)
                return True
        except BaseException as e:
            print("Error on_data: %s" % str(e))
        return True

参考: Twitter流API从None给出JSONDecodeError(“ Expecting value”,s,err.value)


我认为空行不是问题。它明确指出该错误位于第1行的第1列。我认为此替代方法有效,因为它正在从文件中删除BOM。您可以快速进行验证:1.检查原始文件的大小(右键单击>“属性”),可以为134.859字节。2.使用记事本++打开原始文件。3.将编码从“ UTF-8-BOM”更改为“ UTF-8”。保存4.再次检查尺寸。大约是134.856(少3个字节)
Alex 75

0

只需检查请求的状态码是否为200。例如:

if status != 200:
    print("An error has occured. [Status code", status, "]")
else:
    data = response.json() #Only convert to Json when status is OK.
    if not data["elements"]:
        print("Empty JSON")
    else:
        "You can extract data here"

0

我在基于Python的Web API的响应中收到了这样的错误.text,但是它导致了我的到来,因此这可能会帮助遇到类似问题的其他人(使用requests.. 过滤响应并在搜索中请求问题非常困难)

使用json.dumps()要求 data ARG创建JSON的正确转义的字符串前发布解决了该问题对我来说

requests.post(url, data=json.dumps(data))
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.