J'obtiens l'erreur Expecting value: line 1 column 1 (char 0)
en essayant de décoder le JSON.
L'URL que j'utilise pour l'appel d'API fonctionne correctement dans le navigateur, mais renvoie cette erreur lorsque cela est effectué via une requête curl Voici le code que j'utilise pour la requête curl.
L'erreur se produit à 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 complet:
Traceback:
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)
Pour résumer la conversation dans les commentaires:
Il n'est pas nécessaire d'utiliser la bibliothèque simplejson
, la même bibliothèque est incluse dans Python en tant que module json
.
Il n'est pas nécessaire de décoder une réponse d'UTF8 en unicode, la méthode simplejson
/json
.loads()
peut gérer les données codées en UTF8 de manière native.
pycurl
a une API très archaïque. À moins que vous n'ayez une exigence spécifique pour l'utiliser, il existe de meilleurs choix.
requests
offre l'API la plus conviviale, y compris le support JSON. Si vous le pouvez, remplacez votre appel par:
import requests
return requests.get(url).json()
Vérifiez dans le corps de données de la réponse si les données réelles sont présentes et si un vidage de données semble être correctement formaté.
Dans la plupart des cas, votre erreur json.loads
- JSONDecodeError: Expecting value: line 1 column 1 (char 0)
est due à:
En fin de compte, l'erreur vous indique qu'à la toute première position, la chaîne n'est déjà pas conforme à JSON.
En tant que tel, si l'analyse échoue malgré le fait que le corps de données ressemble à au format JSON à première vue, essayez de remplacer les guillemets du corps de données:
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()
Remarque: les citations dans les données doivent être correctement échappées.
Avec requests
lib JSONDecodeError
peut arriver lorsque vous avez un code d'erreur http tel que 404 et que vous essayez d'analyser la réponse au format JSON!
Vous devez d’abord vérifier pour 200 (OK) ou le laisser lever par erreur pour éviter ce cas .. Je souhaite qu’il échoue avec un message d’erreur moins crypté.
NOTE: comme Martijn Pieters l'a indiqué dans les commentaires, les serveurs peuvent répondre avec JSON en cas d'erreur (cela dépend de la mise en oeuvre). Par conséquent, vérifier l'en-tête Content-Type
est plus fiable.
Il peut y avoir des 0 incorporés, même après avoir appelé decode (). Utilisez 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
Souvent, ce sera parce que la chaîne que vous essayez d'analyser est vide:
>>> 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)
Vous pouvez remédier à cela en vérifiant si json_string
est vide au préalable:
import json
if json_string:
x = json.loads(json_string)
else:
// Your logic here
x = {}
vérifiez le format de codage de votre fichier et utilisez le format de codage correspondant lors de la lecture du fichier. Cela résoudra votre problème.
with open("AB.json",encoding='utf-16', errors='ignore') as json_data:
data = json.load(json_data, strict=False)
J'ai eu exactement ce problème en utilisant des demandes. Merci à Christophe Roussy pour son explication.
Pour déboguer, j'ai utilisé:
response = requests.get(url)
logger.info(type(response))
Je recevais une réponse 404 de l'API.
J'avais le même problème avec les requêtes (la bibliothèque python). C'était l'en-tête accept-encoding
.
C'était défini comme suit: 'accept-encoding': 'gzip, deflate, br'
Je l'ai simplement retiré de la demande et j'ai cessé de recevoir l'erreur.