JSONDecodeError: valore previsto: riga 1 colonna 1 (carattere 0)


260

Ricevo un errore Expecting value: line 1 column 1 (char 0)quando provo a decodificare JSON.

L'URL che utilizzo per la chiamata API funziona correttamente nel browser, ma fornisce questo errore quando viene eseguito tramite una richiesta di arricciatura. Di seguito è riportato il codice che utilizzo per la richiesta di arricciatura.

L'errore si verifica a 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 completo:

Rintracciare:

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
Ultimo ma non meno importante, a cosa print repr(response_json)ti viene comunicato .loads()?
Martijn Pieters

4
Ancora uno: perché usarlo simplejsonquando puoi semplicemente usare lo stdlib json(che è la stessa libreria disimplejson )?
Martijn Pieters

3
Questa è una stringa vuota. La tua web_fetch() chiamata non è riuscita.
Martijn Pieters

1
Sì, ti consiglio di usare qualcosa di più facile da usare di pycurl. requestsoffre un'API molto più semplice, soprattutto quando si tratta di debug di ciò che sta succedendo. A meno che non sia necessario disporre di una versione più recente della simplejsonlibreria, attenersi a ciò json, consente di risparmiare una dipendenza da gestire.
Martijn Pieters

1
è response_jsonil valore di ritorno di .json()? Quindi hai già i dati decodificati e non devi json.loads()più utilizzarli . responsedecodificato per te.
Martijn Pieters

Risposte:


125

Per riassumere la conversazione nei commenti:

  • Non è necessario utilizzare la simplejsonlibreria, la stessa libreria è inclusa in Python come il jsonmodulo.

  • Non è necessario decodificare una risposta da UTF8 a Unicode, il metodo simplejson/ json .loads()può gestire nativamente i dati codificati UTF8.

  • pycurlha un'API molto arcaica. A meno che tu non abbia un requisito specifico per usarlo, ci sono scelte migliori.

requestsoffre l'API più intuitiva, incluso il supporto JSON. Se puoi, sostituisci la tua chiamata con:

import requests

return requests.get(url).json()

93
Ricevo lo stesso errore usando requests! La traccia sembra suggerire che requestsusi complexjson, che usa simplejson. Strano.
Rayu,

@Rayu: le richieste verranno utilizzatesimplejson se disponibili; alcune persone vogliono usare l'ultima versione di simplejson piuttosto che quella in bundle con lo stdlib di Python.
Martijn Pieters

5
"Non è necessario utilizzare la libreria simplejson, la stessa libreria è inclusa in Python come il modulo json." ... Rispetto rispettosamente. simplejsonusa il built-in jsonsotto il cofano, ma dà errori più descrittivi. In questo caso l'utilizzo ti jsondarebbe solo un generico ValueError: No JSON object could be decoded.
BoltzmannBrain,

2
Ciò potrebbe essere causato da un json interrotto o incompleto? Lo capisco a caso una volta ogni tanto, non sono sicuro di come riprodurlo.
Christophe Roussy,

2
@ChristopheRoussy: sì, questo è piuttosto il punto della domanda (l'OP ha ottenuto una risposta vuota u'' ). Il tuo JSONDecodeErrorti dice quanti più dati è stato analizzato con successo prima che correva in un errore; ciò può essere dovuto al fatto che a quel punto sono presenti dati non validi (documento JSON non valido o danneggiato) o perché i dati sono stati troncati.
Martijn Pieters

64

Controllare il corpo dei dati di risposta, se sono presenti dati effettivi e un dump dei dati sembra essere ben formattato.

Nella maggior parte dei casi il tuo json.loads- JSONDecodeError: Expecting value: line 1 column 1 (char 0)errore è dovuto a:

  • quotazioni non conformi a JSON
  • Output XML / HTML (ovvero una stringa che inizia con <) o
  • codifica caratteri incompatibile

Alla fine l'errore indica che nella prima posizione la stringa non è già conforme a JSON.

Pertanto, se l'analisi non riesce nonostante abbia un corpo dati che assomiglia a JSON a prima vista, prova a sostituire le virgolette del corpo dati:

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

Nota: le virgolette all'interno dei dati devono essere correttamente ignorate


4
Nei commenti era chiaro che l'OP ha ottenuto una risposta vuota. Dal momento che requests.get(url).json()Just Works, anche JSON non è malformato.
Martijn Pieters

JSONDecodeError: Expecting value: line 1 column 1 (char 0)si verifica in particolare quando una stringa vuota viene passata alla decodifica json
wesinat0r

JSONDecodeError: Expecting value: line 1 column 1 (char 0)si verifica anche quando la prima riga della risposta json non è valida. La risposta di esempio dall'esecuzione di un az clicomando è ["WARNING: The default kind for created storage account will change to 'StorageV2' from 'Storage' in the future", '{',. Questo mi ha dato l'errore che mi ha portato qui. Il resto della risposta È un oggetto json valido. Solo quella prima linea rompe le cose.
SeaDude,

35

Con la requestslib JSONDecodeErrorpuò accadere quando si dispone di un codice di errore http come 404 e si tenta di analizzare la risposta come JSON!

È necessario prima controllare 200 (OK) o lasciarlo sollevare in caso di errore per evitare questo caso. Vorrei che fallisse con un messaggio di errore meno criptico.

NOTA : come indicato da Martijn Pieters nei commenti, i server possono rispondere con JSON in caso di errori (dipende dall'implementazione), quindi il controllo Content-Typedell'intestazione è più affidabile.


Ci scusiamo per il vecchio commento, ma potresti collegare un esempio? Sto provando a prendere le mie abilità da "eseguire un'azione", a "tentare di eseguire un'azione, restituire la risposta, reagire di conseguenza".
dcclassics,

@dcclassics: Esempio: fallisce sul lato server e il server risponde mostrando una pagina di errore (HTML) invece di rispondere con JSON, quindi il codice che analizza la risposta tenterà di leggere JSON ma fallirà sui tag HTML.
Christophe Roussy,

1
I server possono includere corpi JSON nelle risposte agli errori. Non sono solo 200 risposte OK. Si desidera controllare l'intestazione Content-Type.
Martijn Pieters

29

Penso che valga la pena ricordare che nei casi in cui stai analizzando il contenuto di un file JSON stesso, i controlli di integrità possono essere utili per assicurarti che stai effettivamente invocando json.loads()il contenuto del file, al contrario del percorso del file di quel JSON :

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

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

Sono un po 'imbarazzato ad ammettere che questo può accadere a volte:

contents = json.loads(json_file_path)

Beh .. succede a volte. Grazie Ha funzionato tra.
Sachin Kumar,

Penso che in quel caso si dovrebbe usare json.load()invece.
Coddy

13

Controlla il formato di codifica del tuo file e usa il formato di codifica corrispondente durante la lettura del file. Risolverà il tuo problema.

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

3
Questo ha funzionato per me con il piccolo cambio di encoding='utf-8', quindi suppongo che a volte sia necessario provare alcune cose.
RobertMyles,

9

Molte volte, questo sarà perché la stringa che stai cercando di analizzare è vuota:

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

Puoi porre rimedio controllando se json_stringè vuoto in anticipo:

import json

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

Durante il debug più in alto nel mio codice stavo chiamando response.read()e poi sono rimasto sgomento quando è risultata un'altra chiamata Expecting value: line 1ecc. Rimossa l'istruzione di debug e il problema è stato risolto.
Joe,

Per eseguire il debug, puoi anche utilizzare questo simpatico sito Web jsonlint.com
Roelant,

4

Potrebbero esserci degli 0 incorporati, anche dopo aver chiamato decode (). Usa sostituisci ():

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

Ho avuto esattamente questo problema usando le richieste. Grazie a Christophe Roussy per la sua spiegazione.

Per eseguire il debug, ho usato:

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

Stavo ottenendo una risposta 404 dall'API.


1
Può essere semplificato a response.status_codeo print(response.status_code).
TitanFighter

1

Stavo avendo lo stesso problema con le richieste (la libreria Python). È successo che fosse l' accept-encodingintestazione.

È stato impostato in questo modo: 'accept-encoding': 'gzip, deflate, br'

L'ho semplicemente rimosso dalla richiesta e ho smesso di ottenere l'errore.


1

Per me, non stava usando l'autenticazione nella richiesta.


1

Per me è stato il server a rispondere con qualcosa di diverso da 200 e la risposta non è stata formattata json. Ho finito per farlo prima dell'analisi 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

Questo è stato il problema per me. Il codice di stato era 500 (errore interno del server) anziché 200, quindi non è stato restituito alcun json e pertanto non vi era nulla nella riga 1 col 1 del json. È sempre utile verificare che il codice di stato della richiesta sia quello previsto.
giovedì

1

Ho riscontrato lo stesso problema, mentre stampavo la stringa json aperta da un file json, ho scoperto che la stringa json inizia con 'ï »¿', che facendo un po 'di ricerca è dovuta al fatto che il file è decodificato di default con UTF-8, e cambiando la codifica in utf-8-sig, il mark out viene rimosso e carica json senza problemi:

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

0

Se sei un utente Windows, Tweepy API può generare una linea vuota tra gli oggetti dati. A causa di questa situazione, è possibile ottenere l'errore "JSONDecodeError: Expecting value: line 1 column 1 (char 0)". Per evitare questo errore, è possibile eliminare le righe vuote.

Per esempio:

 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

Riferimento: l' API dello stream Twitter fornisce JSONDecodeError ("Expecting value", s, err.value) da None


Non penso che le righe vuote siano un problema. Indica chiaramente che l'errore è nella riga 1 della colonna 1. Penso che questa soluzione alternativa funzioni perché sta rimuovendo la distinta componenti dal file. Puoi verificarlo rapidamente: 1. Controlla la dimensione del tuo file originale (tasto destro> Proprietà), può essere 134.859 byte 2. Apri il file originale con Notepad ++ 3. Cambia la codifica da "UTF-8-BOM" a " UTF-8" . Salva 4. Controlla di nuovo le dimensioni. Può essere 134.856 (3 byte in meno)
Alex 75

0

Controlla solo se la richiesta ha un codice di stato 200. Ad esempio:

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

Ho ricevuto un tale errore nella risposta di un'API Web basata su Python .text, ma mi ha portato qui, quindi questo può aiutare gli altri con un problema simile (è molto difficile filtrare la risposta e richiedere problemi in una ricerca quando si utilizza requests..)

Utilizzando json.dumps()su richiesta data arg per creare una stringa di JSON con escape corretto prima che POSTing risolvesse il problema per me

requests.post(url, data=json.dumps(data))
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.