JSONDecodeError: Giá trị kỳ vọng: dòng 1 cột 1 (char 0)


259

Tôi gặp lỗi Expecting value: line 1 column 1 (char 0)khi cố gắng giải mã JSON.

URL tôi sử dụng cho lệnh gọi API hoạt động tốt trong trình duyệt, nhưng đưa ra lỗi này khi được thực hiện thông qua yêu cầu cuộn tròn. Sau đây là mã tôi sử dụng cho yêu cầu curl.

Lỗi xảy ra tại 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

Trac trở lại đầy đủ:

Tìm lại:

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
Cuối cùng nhưng không kém phần quan trọng, điều gì print repr(response_json)nói với bạn đang được truyền đến .loads()?
Martijn Pieters

4
Một điều nữa: tại sao sử dụng simplejsonkhi bạn chỉ có thể sử dụng stdlib json( cùng thư viện vớisimplejson )?
Martijn Pieters

3
Đó là một chuỗi rỗng. Cuộc web_fetch() gọi của bạn không thành công.
Martijn Pieters

1
Vâng, tôi khuyên bạn nên sử dụng một cái gì đó dễ sử dụng hơn pycurl. requestscung cấp một API dễ dàng hơn nhiều, đặc biệt là khi gỡ lỗi những gì đang diễn ra. Trừ khi bạn đặc biệt phải có một phiên bản mới hơn của simplejsonthư viện, chỉ cần gắn bó json, tiết kiệm cho bạn một sự phụ thuộc để quản lý.
Martijn Pieters

1
response_jsongiá trị trả về của .json()? Sau đó, bạn đã có dữ liệu được giải mã và không cần sử dụng json.loads()nữa. responsegiải mã nó cho bạn.
Martijn Pieters

Câu trả lời:


125

Để tóm tắt cuộc hội thoại trong các ý kiến:

  • Không cần sử dụng simplejsonthư viện, cùng một thư viện được bao gồm với Python nhưjson mô-đun.

  • Không cần giải mã một phản hồi từ UTF8 sang unicode, simplejson/json .loads() phương thức có thể xử lý dữ liệu được mã hóa UTF8 nguyên bản.

  • pycurlcó một API rất cổ xưa. Trừ khi bạn có một yêu cầu cụ thể để sử dụng nó, còn có những lựa chọn tốt hơn.

requestscung cấp API thân thiện nhất, bao gồm hỗ trợ JSON. Nếu bạn có thể, hãy thay thế cuộc gọi của bạn bằng:

import requests

return requests.get(url).json()

93
Tôi đang nhận được cùng một lỗi sử dụng requests! Các dấu vết dường như gợi ý rằng requestssử dụng complexjson, trong đó sử dụng simplejson. Kỳ dị.
rayu

@Rayu: yêu cầu sẽ sử dụngsimplejson nếu có sẵn; một số người muốn sử dụng bản phát hành Simplejson mới nhất thay vì bản phát hành kèm theo stdlib Python.
Martijn Pieters

5
"Không cần sử dụng thư viện Simplejson, cùng một thư viện được bao gồm với Python là mô-đun json." ... Tôi không đồng ý. simplejsonsử dụng tích hợp jsonbên dưới mui xe, nhưng đưa ra nhiều lỗi mô tả hơn. Trong trường hợp này sử dụng jsonsẽ chỉ cung cấp cho bạn một chung chung ValueError: No JSON object could be decoded.
BoltzmannBrain

2
Điều này có thể được gây ra bởi một phá thai hoặc json không đầy đủ? Thỉnh thoảng tôi nhận được điều này một cách ngẫu nhiên, không biết làm thế nào để tái tạo nó.
Barshe Roussy

2
@ChristopheRoussy: vâng, đó đúng là điểm của câu hỏi (OP có câu trả lời trống u'' ). Của bạn JSONDecodeErrorcho bạn biết nhiều dữ liệu đã được phân tích thành công trước khi nó gặp lỗi; điều đó có thể là do có dữ liệu không hợp lệ tại thời điểm đó (tài liệu JSON không đúng định dạng hoặc bị hỏng) hoặc do dữ liệu bị cắt ngắn.
Martijn Pieters

64

Kiểm tra phần thân dữ liệu phản hồi, xem có dữ liệu thực tế hay không và dữ liệu kết xuất có được định dạng tốt hay không.

Trong hầu hết các trường hợp json.loads- JSONDecodeError: Expecting value: line 1 column 1 (char 0)lỗi của bạn là do:

  • trích dẫn không tuân thủ JSON
  • Đầu ra XML / HTML (nghĩa là một chuỗi bắt đầu bằng <) hoặc
  • mã hóa ký tự không tương thích

Cuối cùng, lỗi cho bạn biết rằng tại vị trí đầu tiên, chuỗi đã không tuân thủ JSON.

Như vậy, nếu việc phân tích cú pháp thất bại mặc dù có phần thân dữ liệu trông giống như JSON ngay từ cái nhìn đầu tiên, hãy thử thay thế các trích dẫn của phần thân dữ liệu:

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()

Lưu ý: Báo giá trong dữ liệu phải được thoát đúng


4
Trong các bình luận, rõ ràng OP đã có một phản hồi trống rỗng. Vì requests.get(url).json()Just Works, JSON cũng không phải là định dạng.
Martijn Pieters

JSONDecodeError: Expecting value: line 1 column 1 (char 0)đặc biệt xảy ra khi một chuỗi rỗng được chuyển đến giải mã json
wesinat0r

JSONDecodeError: Expecting value: line 1 column 1 (char 0)cũng xảy ra khi dòng đầu tiên trong phản hồi json không hợp lệ. Ví dụ đáp ứng từ việc chạy một az clilệnh là ["WARNING: The default kind for created storage account will change to 'StorageV2' from 'Storage' in the future", '{',. Điều này đã cho tôi lỗi dẫn tôi đến đây. Phần còn lại của phản hồi IS là một đối tượng json hợp lệ. Chỉ cần dòng đầu tiên phá vỡ mọi thứ.
SeaDude

34

Với requestslib JSONDecodeErrorcó thể xảy ra khi bạn có mã lỗi http như 404 và cố gắng phân tích phản hồi dưới dạng JSON!

Trước tiên, bạn phải kiểm tra 200 (OK) hoặc để lỗi tăng lên để tránh trường hợp này. Tôi ước nó thất bại với một thông báo lỗi ít khó hiểu hơn.

LƯU Ý : như Martijn Pieters đã nêu trong các máy chủ nhận xét có thể phản hồi với JSON trong trường hợp có lỗi (tùy thuộc vào việc triển khai), vì vậy việc kiểm tra Content-Typetiêu đề là đáng tin cậy hơn.


Xin lỗi vì nhận xét cũ, nhưng bạn có thể liên kết đến một ví dụ không? Tôi đang cố gắng đưa các kỹ năng của mình từ "thực hiện hành động", sang "cố gắng thực hiện hành động, trả lời phản hồi, phản ứng tương ứng".
lớp học

@dc classics: Ví dụ: không thành công ở phía máy chủ và máy chủ phản hồi bằng cách hiển thị trang lỗi (HTML) thay vì trả lời bằng JSON, vì vậy mã phân tích cú pháp câu trả lời sẽ cố đọc JSON nhưng sẽ thất bại trên các thẻ HTML.
Barshe Roussy

1
Máy chủ có thể và bao gồm các phần JSON trong các phản hồi lỗi. Đó không chỉ là 200 phản hồi OK. Bạn muốn kiểm tra tiêu đề Kiểu nội dung.
Martijn Pieters

29

Tôi nghĩ rằng nó đáng nói đến là trong trường hợp bạn đang phân tích nội dung của một tập tin JSON tự - kiểm tra sự tỉnh táo có thể hữu ích để đảm bảo rằng bạn đang thực sự gọi json.loads()về nội dung của tập tin, như trái ngược với đường dẫn tập tin đó JSON :

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

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

Tôi hơi xấu hổ khi thừa nhận rằng điều này đôi khi có thể xảy ra:

contents = json.loads(json_file_path)

Vâng .. đôi khi nó xảy ra. Cảm ơn Nó đã làm việc btw.
Sachin Kumar

Tôi nghĩ rằng trong trường hợp đó người ta nên sử dụng json.load()thay thế.
Coddy

13

Kiểm tra định dạng mã hóa của tệp của bạn và sử dụng định dạng mã hóa tương ứng trong khi đọc tệp. Nó sẽ giải quyết vấn đề của bạn.

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

3
Điều này làm việc cho tôi với sự thay đổi nhỏ encoding='utf-8', vì vậy tôi cho rằng đôi khi bạn cần thử một vài điều.
RobertMyles

9

Rất nhiều lần, điều này sẽ là do chuỗi bạn đang cố phân tích trống:

>>> 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)

Bạn có thể khắc phục bằng cách kiểm tra xem json_stringcó trống trước không:

import json

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

Trong khi gỡ lỗi thêm trong mã của tôi, tôi đã gọi response.read()và sau đó bị mất tinh thần khi một cuộc gọi khác dẫn đến, Expecting value: line 1v.v ... Đã xóa câu lệnh gỡ lỗi và giải quyết vấn đề.
Joe

Để gỡ lỗi, bạn cũng có thể sử dụng trang web đẹp này jsonlint.com
Roelant

4

Có thể được nhúng 0, ngay cả sau khi gọi giải mã (). Sử dụng thay thế ():

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

Tôi đã có chính xác vấn đề này bằng cách sử dụng các yêu cầu. Cảm ơn Barshe Roussy vì lời giải thích của anh ấy.

Để gỡ lỗi, tôi đã sử dụng:

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

Tôi đã nhận được phản hồi 404 từ API.


1
Nó có thể được đơn giản hóa để response.status_codehoặc print(response.status_code).
TitanFighter

1

Tôi đã có cùng một vấn đề với các yêu cầu (thư viện python). Nó tình cờ là accept-encodingtiêu đề.

Nó được đặt theo cách này: 'accept-encoding': 'gzip, deflate, br'

Tôi chỉ cần xóa nó khỏi yêu cầu và ngừng nhận lỗi.


1

Đối với tôi, nó không sử dụng xác thực trong yêu cầu.


1

Đối với tôi, đó là máy chủ phản hồi với thứ gì đó ngoài 200 và phản hồi không được định dạng. Tôi đã kết thúc việc này trước khi phân tích 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

Đây là vấn đề đối với tôi. Mã trạng thái là 500 (lỗi máy chủ nội bộ) thay vì 200, vì vậy không có json nào được trả về và do đó không có gì trong dòng 1 col 1 của json. Luôn luôn tốt để kiểm tra xem mã trạng thái yêu cầu là những gì bạn mong đợi.
thposs

0

Nếu bạn là người dùng Windows, Tweepy API có thể tạo một dòng trống giữa các đối tượng dữ liệu. Do tình huống này, bạn có thể gặp lỗi "JSONDecodeError: Expending value: line 1 cột 1 (char 0)". Để tránh lỗi này, bạn có thể xóa các dòng trống.

Ví dụ:

 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

Tham khảo: API luồng Twitter cung cấp cho JSONDecodeError ("Giá trị kỳ vọng", s, err.value) từ Không có


Tôi không nghĩ các dòng trống là một vấn đề. Nó nói rõ rằng lỗi nằm ở dòng 1 cột 1. Tôi nghĩ cách giải quyết này hoạt động vì nó đang xóa BOM khỏi tệp. Bạn có thể nhanh chóng xác minh nó: 1. Kiểm tra kích thước của tệp gốc của bạn (nhấp chuột phải> Thuộc tính), nó có thể là 134.859 byte 2. Mở tệp gốc bằng Notepad ++ 3. Thay đổi Mã hóa từ "UTF-8-BOM" thành " UTF-8 ". Lưu 4. Kiểm tra lại kích thước. Đó là 134.856 (ít hơn 3 byte)
Alex 75

0

Chỉ cần kiểm tra xem yêu cầu có mã trạng thái 200. Ví dụ:

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

Tôi đã nhận được một lỗi như vậy trong phản hồi của API web dựa trên Python .text, nhưng nó đã dẫn tôi đến đây, vì vậy điều này có thể giúp những người khác gặp vấn đề tương tự (rất khó để lọc phản hồi và yêu cầu các vấn đề trong tìm kiếm khi sử dụng requests..)

Sử dụng json.dumps()theo yêu cầu data arg để tạo một chuỗi JSON thoát chính xác trước khi POST đã khắc phục sự cố cho tôi

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

0

Tôi gặp phải vấn đề tương tự, trong khi in chuỗi json được mở từ tệp json, đã tìm thấy chuỗi json bắt đầu bằng 'ï »¿', do thực hiện một số reserach là do tệp được giải mã theo mặc định với UTF-8 và bằng cách thay đổi mã hóa thành utf-8-sig, đánh dấu bị loại bỏ và tải json không có vấn đề gì:

open('test.json', encoding='utf-8-sig')
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.