【问题标题】:JSONDecodeError: Expecting value: line 1 column 1 (char 0)JSONDecodeError:期望值:第 1 行第 1 列(字符 0)
【发布时间】:2013-05-10 12:20:01
【问题描述】:

我在尝试解码 JSON 时收到错误 Expecting value: line 1 column 1 (char 0)

我用于 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)

【问题讨论】:

  • 为什么要解码响应? (simple)json 可以很好地处理 UTF-8 编码的 JSON。
  • 最后但同样重要的是,print repr(response_json) 告诉您什么正在传递给.loads()
  • 还有一个:当你可以使用标准库jsonsimplejson相同的库)时,为什么还要使用simplejson
  • 当我执行print repr(response_json) 时,它只会显示u''
  • 那是一个空字符串。您的web_fetch() 呼叫失败。

标签: python json curl


【解决方案1】:

您的代码生成了一个空的响应正文,您需要检查它或捕获引发的异常。服务器可能以 204 No Content 响应进行响应,或者返回了非 200 范围的状态代码(404 Not Found 等)。检查一下。

注意:

  • 无需使用simplejson 库,Python 中包含与json 模块相同的库。

  • 无需将响应从 UTF8 解码为 un​​icode,simplejson / json .loads() 方法可以原生处理 UTF8 编码数据。

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

requestshttpx 提供了更友好的 API,包括 JSON 支持。如果可以,请将您的电话替换为:

import requests

response = requests.get(url)
response.raise_for_status()  # raises exception when not a 2xx response
if response.status_code != 204:
    return response.json()

当然,这不会保护您免受不符合 HTTP 标准的 URL 的侵害;在可能的情况下使用任意 URL 时,请检查服务器是否打算通过检查 Content-Type 标头为您提供 JSON,并采取良好措施捕获异常:

if (
    response.status_code != 204 and
    response.headers["content-type"].strip().startswith("application/json")
):
    try:
        return response.json()
    except ValueError:
        # decide how to handle a server that's misbehaving to this extent

【讨论】:

    【解决方案2】:

    请务必记住在文件的内容上调用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()
    • 感谢您的精彩回答,这救了我!
    • 两年前我发布了这个答案,但我刚刚犯了同样的错误:(
    【解决方案3】:

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

    在大多数情况下,您的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()
    

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

    【讨论】:

    • 在 cmets 中,很明显 OP 得到了一个空的响应。由于requests.get(url).json() Just Works,JSON 也没有格式错误。
    • JSONDecodeError: Expecting value: line 1 column 1 (char 0) 专门在将空字符串传递给 json decode 时发生
    • 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 对象。只是第一行就打破了一切。
    • 在某些情况下,需要将标头作为headers: { 'Accept': 'application/json', 'Content-Type': 'application/json', } 与请求 URL 一起传递,以便接收有效的 JSON 响应。
    【解决方案4】:

    使用requestsJSONDecodeError 可能会在您有类似 404 的 http 错误代码并尝试将响应解析为 JSON 时发生!

    您必须首先检查 200 (OK) 或让它在错误时引发以避免这种情况。 我希望它以不那么神秘的错误消息而失败。

    注意:正如 Martijn Pieters 在 cmets 服务器中所述,可以在出现错误时使用 JSON 响应(这取决于实现),因此请检查 Content-Type 标头更可靠。

    【讨论】:

    • 抱歉旧评论,但你能链接到一个例子吗?我正在尝试将我的技能从“执行操作”转变为“尝试执行操作、返回响应、做出相应反应”。
    • @dcclassics:示例:它在服务器端失败,服务器通过显示错误页面 (HTML) 而不是使用 JSON 进行响应,因此解析答案的代码将尝试读取 JSON,但会失败在 HTML 标签上。
    • 服务器可以并且确实在错误响应中包含 JSON 正文。这不仅仅是 200 个 OK 响应。您要检查 Content-Type 标头。
    【解决方案5】:

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

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

    【讨论】:

    • encoding='utf-8' 的小改动对我有用,所以我想有时你需要尝试一些事情。
    • 不能同意更多,这真的取决于设置...
    【解决方案6】:

    我在尝试读取 json 文件时遇到了同样的问题

    json.loads("file.json")
    

    我解决了这个问题

    with open("file.json", "r") as read_file:
       data = json.load(read_file)
    

    也许这对你有帮助

    【讨论】:

      【解决方案7】:

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

      >>> 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 code/logic here 
          x = {}
      

      【讨论】:

      • 在我的代码中进一步调试时,我调用了response.read(),然后当另一个调用导致Expecting value: line 1 等时感到沮丧。删除了调试语句并解决了问题。
      • 调试,也可以使用这个不错的网站jsonlint.com
      【解决方案8】:

      我遇到了同样的问题,在打印从 json 文件打开的 json 字符串时,发现 json 字符串以 '' 开头,通过进行一些研究是由于文件默认使用 UTF- 8、通过把编码改成utf-8-sig,去掉mark out,加载json没问题:

      open('test.json', encoding='utf-8-sig')
      

      【讨论】:

      • 解决了我的问题。与您的描述几乎相同,开头有一些奇怪的字符串。非常感谢。
      【解决方案9】:

      我收到此错误是因为我的 json 文件为空。

      【讨论】:

        【解决方案10】:

        即使在调用 decode() 之后,也可能嵌入 0。使用替换():

        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
        

        【讨论】:

        • response_json 未定义
        • 原发帖者将响应 json 称为 response_json 。
        【解决方案11】:

        我有同样的问题,在我的情况下,我是这样解决的:

        import json
        
        with open("migrate.json", "rb") as read_file:
           data = json.load(read_file)
        

        【讨论】:

          【解决方案12】:

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

          为了调试,我使用了:

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

          我从 API 收到了 404 响应。

          【讨论】:

          • 可以简化为response.status_codeprint(response.status_code)
          • 相同。我收到 403 错误。所以我的回复看起来像这样,&lt;Response [403]&gt; 这不是有效的 json 格式
          【解决方案13】:

          只需检查请求的状态码是否为 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"
          

          【讨论】:

            【解决方案14】:

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

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

            我只是从请求中删除它并停止收到错误。

            【讨论】:

              【解决方案15】:

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

              【讨论】:

                【解决方案16】:

                对我来说,服务器响应的不是 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 行中没有任何内容。检查请求状态代码是否符合您的预期总是很好。
                【解决方案17】:

                我在基于 Python 的 Web API 的响应 .text 中收到了这样一个错误,但它把我带到了这里,所以这可能会帮助其他有类似问题的人(使用时很难在搜索中过滤响应和请求问题) requests..)

                request data arg 上使用 json.dumps() 在 POST 为我解决问题之前创建正确转义的 JSON 字符串

                requests.post(url, data=json.dumps(data))
                

                【讨论】:

                  【解决方案18】:

                  我做到了:

                  1. 打开test.txt文件,写入数据
                  2. 打开test.txt文件,读取数据

                  所以我在 1 之后没有关闭文件。

                  我加了

                  outfile.close()
                  

                  现在可以了

                  【讨论】:

                  • 我在使用两个 with 语句时也遇到了类似的问题,即使它应该自己处理关闭
                  【解决方案19】:

                  这是我想在python中加载json文件时找到的极简解决方案

                  import json
                  data = json.load(open('file_name.json'))
                  

                  如果这给出错误提示字符在位置 X 和 Y 上不匹配,则只需在 open 圆括号内添加 encoding='utf-8'

                  data = json.load(open('file_name.json', encoding='utf-8'))
                  

                  说明 open 打开文件并读取随后在json.load 中解析的内容。

                  请注意,使用with open() as f 比上述语法更可靠,因为它确保文件在执行后关闭,完整的语法将是

                  with open('file_name.json') as f:
                      data = json.load(f)
                  

                  【讨论】:

                    【解决方案20】:

                    在我的情况下,我在 if 和 else 块中执行了两次 file.read() ,这导致了这个错误。所以请确保不要犯这个错误,并在变量中保存包含并多次使用变量。

                    【讨论】:

                      【解决方案21】:

                      如果您是 Windows 用户,Tweepy API 可以在数据对象之间生成一个空行。由于这种情况,您可能会收到“JSONDecodeError: Expecting value: line 1 column 1 (char 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 stream API gives JSONDecodeError("Expecting value", s, err.value) from None

                      【讨论】:

                      • 我认为空行不是问题。它清楚地指出错误位于第 1 行第 1 列。我认为这种解决方法有效,因为它正在从文件中删除 BOM。您可以快速验证一下: 1. 检查原始文件的大小(右键单击>属性),可以是 134.859 字节 2. 使用 Notepad++ 打开原始文件 3. 将编码从“UTF-8-BOM”更改为“ UTF-8”。保存 4. 再次检查大小。它可以是 134.856(少 3 个字节)
                      【解决方案22】:

                      在我的情况下,这是因为服务器偶尔会给出 http 错误。所以基本上偶尔我的脚本会得到这样的响应,而不是预期的响应:

                      <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
                      <html>
                      <head><title>502 Bad Gateway</title></head>
                      <body bgcolor="white">
                      <h1>502 Bad Gateway</h1>
                      <p>The proxy server received an invalid response from an upstream server.<hr/>Powered by Tengine</body>
                      </html>
                      

                      显然这不是 json 格式,尝试调用 .json() 将产生 JSONDecodeError: Expecting value: line 1 column 1 (char 0)

                      您可以打印导致此错误的确切响应,以便更好地调试。 例如,如果您使用requests,然后只需打印.text 字段(在您调用.json() 之前)就可以了。

                      【讨论】:

                        猜你喜欢
                        • 2019-02-25
                        • 2018-06-28
                        • 2018-08-28
                        • 2020-10-10
                        • 1970-01-01
                        • 1970-01-01
                        • 2019-07-04
                        • 2020-02-03
                        相关资源
                        最近更新 更多