JSONDecodeError: Nilai yang diharapkan: baris 1 kolom 1 (karakter 0)

260

Saya mendapatkan kesalahan Expecting value: line 1 column 1 (char 0)saat mencoba men-decode JSON.

URL yang saya gunakan untuk panggilan API berfungsi dengan baik di browser, tetapi memberikan kesalahan ini ketika dilakukan melalui permintaan ikal. Berikut ini adalah kode yang saya gunakan untuk permintaan ikal.

Kesalahan terjadi pada 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

Traceback Penuh:

Melacak kembali:

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)
pengguna1328021
sumber
2
Terakhir tapi tidak kalah pentingnya, apa yang print repr(response_json)memberitahu Anda sedang diteruskan .loads()?
Martijn Pieters
4
Satu lagi: mengapa menggunakan simplejsonketika Anda bisa menggunakan stdlib json(yang merupakan pustaka yang samasimplejson )?
Martijn Pieters
3
Itu adalah string kosong. web_fetch() Panggilan Anda gagal.
Martijn Pieters
1
Ya, saya sarankan Anda menggunakan sesuatu yang lebih mudah digunakan daripada pycurl. requestsmenawarkan API yang jauh lebih mudah, terutama untuk debugging apa yang sedang terjadi. Kecuali Anda secara khusus harus memiliki versi simplejsonperpustakaan yang lebih baru, tetap saja json, menghemat ketergantungan Anda untuk mengelola.
Martijn Pieters
1
adalah response_jsonnilai pengembalian .json()? Maka Anda sudah memiliki data yang diterjemahkan dan tidak perlu digunakan json.loads()lagi. responsemenerjemahkannya untukmu.
Martijn Pieters

Jawaban:

125

Untuk meringkas percakapan dalam komentar:

  • Tidak perlu menggunakan simplejsonpustaka, pustaka yang sama disertakan dengan jsonmodul Python .

  • Tidak perlu men-decode respons dari UTF8 ke unicode, metode simplejson/ json .loads()dapat menangani data yang disandikan UTF8 secara asli.

  • pycurlmemiliki API yang sangat kuno. Kecuali Anda memiliki persyaratan khusus untuk menggunakannya, ada pilihan yang lebih baik.

requestsmenawarkan API paling ramah, termasuk dukungan JSON. Jika Anda bisa, ganti panggilan Anda dengan:

import requests

return requests.get(url).json()
Martijn Pieters
sumber
93
Saya mendapatkan kesalahan yang sama ini menggunakan requests! Jejak tampaknya menyarankan requestspenggunaan itu complexjson, yang menggunakan simplejson. Aneh.
rayu
@Rayu: permintaan akan digunakansimplejson jika tersedia; beberapa orang ingin menggunakan rilis simplejson terbaru daripada yang dibundel dengan stdlib Python.
Martijn Pieters
5
"Tidak perlu menggunakan perpustakaan simplejson, perpustakaan yang sama disertakan dengan Python sebagai modul json." ... Saya dengan hormat tidak setuju. simplejsonmenggunakan built-in di jsonbawah tenda, tetapi memberikan lebih banyak kesalahan deskriptif. Dalam hal ini menggunakan jsonhanya akan memberi Anda obat generik ValueError: No JSON object could be decoded.
BoltzmannBrain
2
Mungkinkah ini disebabkan oleh abon yang dibatalkan atau tidak lengkap? Saya mendapatkan ini secara acak sesekali, tidak yakin bagaimana cara membuatnya.
Christophe Roussy
2
@ChristopheRoussy: ya, itu agak inti dari pertanyaan (OP mendapat jawaban kosong u'' ). Anda JSONDecodeErrormemberi tahu Anda banyak data yang berhasil diuraikan sebelum mengalami kesalahan; itu bisa karena ada data yang tidak valid pada saat itu (dokumen JSON rusak atau rusak) atau karena data terpotong.
Martijn Pieters
64

Periksa badan data tanggapan, apakah ada data aktual dan dump data tampaknya diformat dengan baik.

Dalam kebanyakan kasus json.loads- JSONDecodeError: Expecting value: line 1 column 1 (char 0)kesalahan Anda disebabkan oleh:

  • kutipan non-JSON sesuai
  • Output XML / HTML (yaitu, string yang dimulai dengan <), atau
  • pengkodean karakter yang tidak kompatibel

Pada akhirnya kesalahan memberitahu Anda bahwa pada posisi pertama string sudah tidak sesuai dengan JSON.

Dengan demikian, jika parsing gagal meskipun memiliki data-body yang terlihat seperti JSON pada pandangan pertama, coba ganti kutipan dari data-body:

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

Catatan: Kutipan dalam data harus lolos dengan benar

Lorenz Lo Sauer
sumber
4
Dalam komentar itu jelas OP mendapat jawaban kosong. Sejak requests.get(url).json()Just Works, JSON juga tidak cacat.
Martijn Pieters
JSONDecodeError: Expecting value: line 1 column 1 (char 0)secara khusus terjadi ketika string kosong diteruskan ke json decode
wesinat0r
JSONDecodeError: Expecting value: line 1 column 1 (char 0)juga terjadi ketika baris pertama dalam respons json tidak valid. Contoh respons dari menjalankan az cliperintah adalah ["WARNING: The default kind for created storage account will change to 'StorageV2' from 'Storage' in the future", '{',. Ini memberi saya kesalahan yang membawa saya ke sini. Sisa dari respons ADALAH objek json yang valid. Hanya saja baris pertama merusak segalanya.
SeaDude
35

Dengan requestslib JSONDecodeErrordapat terjadi ketika Anda memiliki kode kesalahan http seperti 404 dan mencoba untuk menguraikan respons sebagai JSON!

Anda harus terlebih dahulu memeriksa 200 (OK) atau membiarkannya meningkatkan kesalahan untuk menghindari kasus ini. Saya berharap itu gagal dengan pesan kesalahan yang kurang samar.

CATATAN : seperti yang dinyatakan Martijn Pieters di server komentar dapat merespons dengan JSON jika terjadi kesalahan (tergantung pada implementasinya), jadi memeriksa Content-Typeheader lebih dapat diandalkan.

Christophe Roussy
sumber
Maaf atas komentar lama, tetapi bisakah Anda menautkan ke contoh? Saya mencoba untuk mengambil keterampilan saya dari "melakukan tindakan", untuk "mencoba melakukan tindakan, mengembalikan respons, bereaksi sesuai".
dcclassics
@dcclassics: Contoh: gagal di sisi server dan server merespons dengan menunjukkan halaman kesalahan (HTML) alih-alih menjawab dengan JSON, jadi kode yang menguraikan jawaban akan berusaha membaca JSON tetapi gagal pada tag HTML.
Christophe Roussy
1
Server dapat dan memang menyertakan tubuh JSON dalam respons kesalahan. Bukan hanya 200 respons OK. Anda ingin memeriksa header Tipe Konten.
Martijn Pieters
29

Saya pikir perlu disebutkan bahwa dalam kasus-kasus di mana Anda mem-parsing isi dari file JSON itu sendiri - cek kewarasan dapat berguna untuk memastikan bahwa Anda benar-benar memohon json.loads()pada isi file, sebagai lawan dari path file JSON itu :

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

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

Saya agak malu untuk mengakui bahwa ini kadang-kadang bisa terjadi:

contents = json.loads(json_file_path)
alex
sumber
Ya .. Terkadang itu terjadi. Terima kasih ini berhasil btw.
Sachin Kumar
Saya pikir dalam hal ini yang harus digunakan json.load()sebagai gantinya.
Coddy
13

Periksa format penyandian file Anda dan gunakan format penyandian yang sesuai saat membaca file. Itu akan menyelesaikan masalah Anda.

with open("AB.json", encoding='utf-8', errors='ignore') as json_data:
     data = json.load(json_data, strict=False)
Ramineni Ravi Teja
sumber
3
Ini bekerja untuk saya dengan perubahan kecil encoding='utf-8', jadi saya kira kadang-kadang Anda perlu mencoba beberapa hal.
RobertMyles
9

Sering kali, ini karena string yang Anda coba parsing kosong:

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

Anda dapat memperbaiki dengan memeriksa apakah json_stringkosong sebelumnya:

import json

if json_string:
    x = json.loads(json_string)
else:
    // Your logic here
    x = {}
Alex W
sumber
Saat debugging lebih lanjut dalam kode saya, saya menelepon response.read()dan kemudian kecewa ketika panggilan lain menghasilkan Expecting value: line 1dll. Dihapus pernyataan debug dan masalah diselesaikan.
Joe
Untuk debug, Anda juga dapat menggunakan situs web yang bagus ini jsonlint.com
Roelant
4

Mungkin ada 0 tertanam, bahkan setelah memanggil decode (). Gunakan ganti ():

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
Bryan
sumber
2

Saya benar-benar mengalami masalah ini menggunakan permintaan. Terima kasih kepada Christophe Roussy untuk penjelasannya.

Untuk debug, saya menggunakan:

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

Saya mendapat respons 404 kembali dari API.

Kelsie Braidwood
sumber
1
Ini dapat disederhanakan menjadi response.status_codeatau print(response.status_code).
TitanFighter
1

Saya mengalami masalah yang sama dengan permintaan (perpustakaan python). Itu adalah accept-encodingheader.

Diatur seperti ini: 'accept-encoding': 'gzip, deflate, br'

Saya hanya menghapusnya dari permintaan dan berhenti mendapatkan kesalahan.

Seu Madruga
sumber
1

Bagi saya, itu tidak menggunakan otentikasi dalam permintaan.

Neel0507
sumber
1

Bagi saya itu adalah server yang merespons dengan sesuatu selain 200 dan responsnya tidak diformat json. Saya akhirnya melakukan ini sebelum json parse:

# 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
FastGTR
sumber
Ini masalah bagi saya. Kode status adalah 500 (kesalahan server internal) alih-alih 200, jadi tidak ada json yang dikembalikan dan oleh karena itu tidak ada apa pun di baris 1 col 1 dari json. Selalu baik untuk memeriksa bahwa kode status permintaan sesuai dengan yang Anda harapkan.
thposs
1

Saya mengalami masalah yang sama, ketika mencetak string json dibuka dari file json, menemukan string json dimulai dengan 'ï »¿', yang dengan melakukan beberapa penelitian karena file secara default diterjemahkan dengan UTF-8, dan dengan mengubah pengodean ke utf-8-sig, tanda keluar dilucuti dan memuat json tidak masalah:

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

Jika Anda adalah pengguna Windows, Tweepy API dapat menghasilkan garis kosong antara objek data. Karena situasi ini, Anda bisa mendapatkan kesalahan "JSONDecodeError: Nilai yang diharapkan: baris 1 kolom 1 (char 0)". Untuk menghindari kesalahan ini, Anda dapat menghapus baris kosong.

Sebagai contoh:

 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

Referensi: Twitter stream API memberikan JSONDecodeError ("Nilai yang diharapkan", s, err.value) dari Tidak Ada

drorhun
sumber
Saya tidak berpikir baris kosong adalah masalah. Ini dengan jelas menyatakan bahwa kesalahan ada pada baris 1 kolom 1. Saya pikir solusi ini berfungsi karena menghapus BOM dari file. Anda dapat dengan cepat memverifikasi: 1. Periksa ukuran file asli Anda (klik kanan> Properti), itu bisa menjadi 134,859 byte 2. Buka file asli dengan Notepad ++ 3. Ubah Encoding dari "UTF-8-BOM" ke " UTF-8 ". Simpan 4. Periksa ukuran lagi. Ini bisa menjadi 134.856 (kurang dari 3 byte)
Alex 75
0

Periksa apakah permintaan memiliki kode status 200. Jadi misalnya:

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"
Wout VC
sumber
0

Saya menerima kesalahan seperti itu dalam respons API web berbasis Python .text, tetapi itu menuntun saya ke sini, jadi ini dapat membantu orang lain dengan masalah serupa (sangat sulit untuk menyaring respons dan meminta masalah dalam pencarian saat menggunakan requests..)

Menggunakan json.dumps()pada request data arg untuk membuat string JSON yang lolos dengan benar sebelum POSTing memperbaiki masalah untuk saya

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