JSONDecodeError: Erwarteter Wert: Zeile 1, Spalte 1 (Zeichen 0)

259

Expecting value: line 1 column 1 (char 0)Beim Versuch, JSON zu dekodieren , wird eine Fehlermeldung angezeigt.

Die URL, die ich für den API-Aufruf verwende, funktioniert im Browser einwandfrei, gibt diesen Fehler jedoch aus, wenn dies über eine Curl-Anforderung erfolgt. Das Folgende ist der Code, den ich für die Curl-Anfrage verwende.

Der Fehler tritt bei auf 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

Vollständiger Traceback:

Zurück verfolgen:

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)
user1328021
quelle
2
Zu guter Letzt, was sagt print repr(response_json)Ihnen, wird weitergegeben .loads()?
Martijn Pieters
4
Noch eines: Warum verwenden, simplejsonwenn Sie nur die stdlib verwenden können json(die dieselbe Bibliothek wiesimplejson )?
Martijn Pieters
3
Das ist eine leere Zeichenfolge. Ihr web_fetch() Anruf ist fehlgeschlagen.
Martijn Pieters
1
Ja, ich empfehle Ihnen, etwas zu verwenden , das einfacher zu verwenden ist als pycurl. requestsbietet eine weitaus einfachere API, insbesondere beim Debuggen von Vorgängen. Wenn Sie nicht speziell über eine neuere Version der simplejsonBibliothek verfügen müssen , bleiben jsonSie einfach bei , um eine zu verwaltende Abhängigkeit zu vermeiden.
Martijn Pieters
1
ist response_jsonder Rückgabewert von .json()? Dann haben Sie bereits Daten dekodiert und müssen diese nicht json.loads()mehr verwenden. responseentschlüsselt es für Sie.
Martijn Pieters

Antworten:

124

Um das Gespräch in den Kommentaren zusammenzufassen:

  • Es ist nicht erforderlich, eine simplejsonBibliothek zu verwenden. Python enthält dieselbe Bibliothek wie das jsonModul.

  • Es ist nicht erforderlich, eine Antwort von UTF8 auf Unicode zu dekodieren. Die Methode simplejson/ json .loads()kann UTF8-codierte Daten nativ verarbeiten.

  • pycurlhat eine sehr archaische API. Sofern Sie keine besonderen Anforderungen für die Verwendung haben, gibt es bessere Möglichkeiten.

requestsbietet die benutzerfreundlichste API, einschließlich JSON-Unterstützung. Wenn Sie können, ersetzen Sie Ihren Anruf durch:

import requests

return requests.get(url).json()
Martijn Pieters
quelle
93
Ich erhalte den gleichen Fehler mit requests! Die Spur scheint darauf hinzudeuten, dass requestsverwendet complexjson, welche verwendet simplejson. Seltsam.
Rayu
@ Rayu: Anfragen werden verwendet,simplejson falls verfügbar; Einige Benutzer möchten die neueste simplejson-Version verwenden, anstatt die mit der Python-stdlib gelieferte.
Martijn Pieters
5
"Es ist nicht erforderlich, die simplejson-Bibliothek zu verwenden. Python enthält dieselbe Bibliothek wie das json-Modul." ... Ich bin mit Respekt anderer Meinung. simplejsonverwendet das eingebaute jsonunter der Haube, gibt aber beschreibendere Fehler. In diesem Fall jsonwürde die Verwendung nur ein Generikum geben ValueError: No JSON object could be decoded.
BoltzmannBrain
2
Könnte dies durch einen Abbruch oder einen unvollständigen JSON verursacht werden? Ich bekomme das ab und zu zufällig und bin mir nicht sicher, wie ich es reproduzieren soll.
Christophe Roussy
2
@ChristopheRoussy: Ja, das ist eher der Punkt der Frage (das OP hat eine leere u'' Antwort erhalten). Sie JSONDecodeErrorsagen Ihnen, dass viele Daten erfolgreich analysiert wurden, bevor ein Fehler auftrat. Dies kann daran liegen, dass zu diesem Zeitpunkt ungültige Daten vorhanden sind (fehlerhaftes oder beschädigtes JSON-Dokument) oder dass die Daten abgeschnitten wurden.
Martijn Pieters
64

Überprüfen Sie den Antwortdatenkörper, ob tatsächliche Daten vorhanden sind und ein Datendump gut formatiert zu sein scheint.

In den meisten Fällen Ihre json.loads- JSONDecodeError: Expecting value: line 1 column 1 (char 0)Fehler wird durch:

  • nicht JSON-konformes Zitat
  • XML / HTML-Ausgabe (dh eine Zeichenfolge, die mit <beginnt) oder
  • inkompatible Zeichenkodierung

Letztendlich sagt Ihnen der Fehler, dass die Zeichenfolge bereits an der ersten Position nicht mit JSON übereinstimmt.

Wenn die Analyse trotz eines Datenkörpers fehlschlägt, der auf den ersten Blick wie JSON aussieht , ersetzen Sie die Anführungszeichen des Datenkörpers:

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

Hinweis: Anführungszeichen in den Daten müssen ordnungsgemäß maskiert werden

Lorenz Lo Sauer
quelle
4
In den Kommentaren war klar, dass das OP eine leere Antwort erhielt. Seit requests.get(url).json()Just Works ist der JSON auch nicht fehlerhaft.
Martijn Pieters
JSONDecodeError: Expecting value: line 1 column 1 (char 0)tritt insbesondere auf, wenn eine leere Zeichenfolge an json
decode übergeben wird
JSONDecodeError: Expecting value: line 1 column 1 (char 0)tritt auch auf, wenn die erste Zeile in der json-Antwort ungültig ist. Beispielantwort vom Ausführen eines az cliBefehls ist ["WARNING: The default kind for created storage account will change to 'StorageV2' from 'Storage' in the future", '{',. Dies gab mir den Fehler, der mich hierher führte. Der Rest der Antwort ist ein gültiges JSON-Objekt. Nur diese erste Zeile bricht die Dinge.
SeaDude
34

Mit der requestslib JSONDecodeErrorkann passieren, wenn Sie einen http-Fehlercode wie 404 haben und versuchen, die Antwort als JSON zu analysieren!

Sie müssen zuerst nach 200 (OK) suchen oder es bei einem Fehler auslösen lassen, um diesen Fall zu vermeiden. Ich wünschte, es wäre mit einer weniger kryptischen Fehlermeldung fehlgeschlagen.

HINWEIS : Wie Martijn Pieters in den Kommentaren angegeben hat, können Server bei Fehlern mit JSON antworten (dies hängt von der Implementierung ab), sodass die Überprüfung des Content-TypeHeaders zuverlässiger ist.

Christophe Roussy
quelle
Entschuldigung für den alten Kommentar, aber könnten Sie auf ein Beispiel verlinken? Ich versuche, meine Fähigkeiten von "Aktion ausführen" zu "Aktion ausführen, Antwort zurückgeben, entsprechend reagieren" zu nutzen.
Dcclassics
@dcclassics: Beispiel: Es schlägt serverseitig fehl und der Server zeigt eine Fehlerseite (HTML) an, anstatt mit JSON zu antworten. Der Code, der die Antwort analysiert, versucht also, JSON zu lesen, schlägt jedoch bei den HTML-Tags fehl.
Christophe Roussy
1
Server können JSON-Body in Fehlerantworten einbeziehen. Es sind nicht nur 200 OK-Antworten. Sie möchten den Content-Type-Header überprüfen.
Martijn Pieters
29

Ich denke, es ist erwähnenswert, dass in Fällen, in denen Sie den Inhalt einer JSON-Datei selbst analysieren, Sanity Checks hilfreich sein können, um sicherzustellen, dass Sie tatsächlich json.loads()den Inhalt der Datei aufrufen , im Gegensatz zum Dateipfad dieses JSON ::

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

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

Es ist mir ein wenig peinlich zuzugeben, dass dies manchmal passieren kann:

contents = json.loads(json_file_path)
Alex
quelle
Nun ... es kommt manchmal vor. Danke Es hat übrigens funktioniert.
Sachin Kumar
Ich denke in diesem Fall sollte man json.load()stattdessen verwenden.
Coddy
13

Überprüfen Sie das Codierungsformat Ihrer Datei und verwenden Sie beim Lesen der Datei das entsprechende Codierungsformat. Es wird Ihr Problem lösen.

with open("AB.json", encoding='utf-8', errors='ignore') as json_data:
     data = json.load(json_data, strict=False)
Ramineni Ravi Teja
quelle
3
Das hat bei mir mit der kleinen Änderung von funktioniert encoding='utf-8', also muss man manchmal ein paar Dinge ausprobieren.
RobertMyles
9

Dies liegt häufig daran, dass die Zeichenfolge, die Sie analysieren möchten, leer ist:

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

Sie können Abhilfe schaffen, indem Sie json_stringvorher prüfen, ob es leer ist:

import json

if json_string:
    x = json.loads(json_string)
else:
    // Your logic here
    x = {}
Alex W.
quelle
Während ich weiter oben in meinem Code debuggte, rief ich an response.read()und war dann bestürzt, als ein weiterer Aufruf zu Expecting value: line 1usw. führte . Die Debug-Anweisung wurde entfernt und das Problem behoben.
Joe
Zum Debuggen können Sie auch diese schöne Website jsonlint.com
Roelant
4

Es können eingebettete Nullen vorhanden sein, auch nach dem Aufruf von decode (). Verwenden Sie 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
Bryan
quelle
2

Ich hatte genau dieses Problem mit Anfragen. Vielen Dank an Christophe Roussy für seine Erklärung.

Zum Debuggen habe ich verwendet:

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

Ich habe eine 404-Antwort von der API erhalten.

Kelsie Braidwood
quelle
1
Es kann zu response.status_codeoder vereinfacht werden print(response.status_code).
TitanFighter
1

Ich hatte das gleiche Problem mit Anfragen (die Python-Bibliothek). Es war zufällig der accept-encodingHeader.

Es wurde so eingestellt: 'accept-encoding': 'gzip, deflate, br'

Ich habe es einfach aus der Anfrage entfernt und den Fehler nicht mehr erhalten.

Seu Madruga
quelle
1

Für mich wurde in der Anfrage keine Authentifizierung verwendet.

Neel0507
quelle
1

Für mich war es ein Server, der mit etwas anderem als 200 antwortete, und die Antwort war nicht json-formatiert. Ich habe das vor der JSON-Analyse gemacht:

# 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
quelle
Das war das Problem für mich. Der Statuscode war 500 (interner Serverfehler) anstelle von 200, daher wurde kein JSON zurückgegeben, und daher befand sich in Zeile 1 Spalte 1 des JSON nichts. Es ist immer gut zu überprüfen, ob der Anforderungsstatuscode Ihren Erwartungen entspricht.
Thposs
0

Wenn Sie ein Windows-Benutzer sind, kann die Tweepy-API eine leere Zeile zwischen Datenobjekten generieren. Aufgrund dieser Situation kann der Fehler "JSONDecodeError: Erwarteter Wert: Zeile 1, Spalte 1 (Zeichen 0)" angezeigt werden. Um diesen Fehler zu vermeiden, können Sie leere Zeilen löschen.

Beispielsweise:

 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

Referenz: Die Twitter-Stream-API gibt JSONDecodeError ("Expecting value", s, err.value) von None an

Drorhun
quelle
Ich denke nicht, dass leere Zeilen ein Problem sind. Es wird eindeutig angegeben, dass sich der Fehler in Zeile 1, Spalte 1 befindet. Ich denke, diese Problemumgehung funktioniert, da die Stückliste aus der Datei entfernt wird. Sie können dies schnell überprüfen: 1. Überprüfen Sie die Größe Ihrer Originaldatei (Rechtsklick> Eigenschaften), sie kann 134,859 Byte betragen. 2. Öffnen Sie die Originaldatei mit Notepad ++. 3. Ändern Sie die Codierung von "UTF-8-BOM" in ". UTF-8 ". Speichern 4. Überprüfen Sie die Größe erneut. Es kann 134,856 (3 Bytes weniger) sein
Alex 75
0

Überprüfen Sie einfach, ob die Anfrage den Statuscode 200 hat. So zum Beispiel:

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
quelle
0

Ich habe einen solchen Fehler in der Antwort einer Python-basierten Web-API erhalten .text, der mich jedoch hierher geführt hat. Dies kann anderen bei einem ähnlichen Problem helfen (es ist sehr schwierig, Antwort- und Anforderungsprobleme bei einer Suche zu filtern, wenn requests..).

Die Verwendung json.dumps()des Anforderungsarguments data zum Erstellen einer korrekt maskierten JSON-Zeichenfolge vor dem POSTing hat das Problem für mich behoben

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

Ich habe das gleiche Problem festgestellt, als ich die aus einer JSON-Datei geöffnete JSON-Zeichenfolge ausgedruckt habe und festgestellt habe, dass die JSON-Zeichenfolge mit 'ï »¿' beginnt Durch Ändern der Codierung in utf-8-sig wird die Markierung entfernt und json wird problemlos geladen:

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