JSONDecodeError: Valor esperado: linha 1 coluna 1 (caractere 0)

259

Estou recebendo erro Expecting value: line 1 column 1 (char 0) ao tentar decodificar JSON.

O URL que eu uso para a chamada da API funciona bem no navegador, mas fornece esse erro quando feito por meio de uma solicitação de curl. A seguir está o código que eu uso para a solicitação de ondulação.

O erro acontece em 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:

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)
user1328021
fonte
2
Por último, mas não menos importante, o que print repr(response_json)diz a você que está sendo passado .loads()?
Martijn Pieters
4
Mais uma: por que usar simplejsonquando você pode simplesmente usar o stdlib json(que é a mesma biblioteca quesimplejson )?
Martijn Pieters
3
Essa é uma string vazia. Sua web_fetch() chamada falhou.
Martijn Pieters
1
Sim, eu recomendo que você use algo mais fácil de usar do que pycurl. requestsoferece uma API muito mais fácil, especialmente quando se trata de depurar o que está acontecendo. A menos que você precise especificamente de uma versão mais recente da simplejsonbiblioteca, fique jsonatento, economizando uma dependência para gerenciar.
Martijn Pieters
1
é response_jsono valor de retorno de .json()? Então você decodificou os dados e não precisa json.loads()mais usá- los. responsedecodificado para você.
Martijn Pieters

Respostas:

125

Para resumir a conversa nos comentários:

  • Não há necessidade de usar simplejson biblioteca, a mesma biblioteca está incluída no Python como o jsonmódulo.

  • Não há necessidade de decodificar uma resposta de UTF8 para unicode, o simplejsonjson .loads() método / pode manipular dados codificados em UTF8 nativamente.

  • pycurltem uma API muito arcaica. A menos que você tenha um requisito específico para usá-lo, existem melhores opções.

requestsoferece a API mais amigável, incluindo suporte a JSON. Se puder, substitua sua chamada por:

import requests

return requests.get(url).json()
Martijn Pieters
fonte
93
Estou recebendo esse mesmo erro usando requests! O traço parece sugerir que requestsusos complexjson, quais usos simplejson. Esquisito.
Rayu
@ Rayu: solicitações serão usadassimplejson se disponíveis; algumas pessoas desejam usar a versão mais recente do simplejson, em vez da que acompanha o stdlib do Python.
Martijn Pieters
5
"Não há necessidade de usar a biblioteca simplejson, a mesma biblioteca está incluída no Python como o módulo json." ... Discordo respeitosamente. simplejsonusa o built-in jsonsob o capô, mas fornece mais erros descritivos. Nesse caso, usar jsonapenas daria a você um genérico ValueError: No JSON object could be decoded.
BoltzmannBrain
2
Isso pode ser causado por um json anulado ou incompleto? Eu entendo isso aleatoriamente de vez em quando, não sei como reproduzi-lo.
Christophe Roussy
2
@ChristopheRoussy: sim, esse é o objetivo da pergunta (o OP teve uma resposta vazia u'' ). Você JSONDecodeErrorinforma que muitos dados foram analisados ​​com sucesso antes de ocorrerem um erro; isso pode ocorrer porque há dados inválidos nesse ponto (documento JSON malformado ou corrompido) ou porque os dados foram truncados.
Martijn Pieters
64

Verifique o corpo de dados da resposta, se há dados reais e se um despejo de dados parece estar bem formatado.

Na maioria dos casos o seu json.loads- JSONDecodeError: Expecting value: line 1 column 1 (char 0)erro é devido a:

  • citações não conformes com JSON
  • Saída XML / HTML (ou seja, uma sequência iniciada por <) ou
  • codificação de caracteres incompatível

Por fim, o erro informa que, na primeira posição, a sequência já não está em conformidade com o JSON.

Como tal, se a análise falhar, apesar de ter um corpo de dados semelhante ao JSON à primeira vista, tente substituir as aspas do corpo de dados:

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: As cotações nos dados devem ser escapadas corretamente

Lorenz Lo Sauer
fonte
4
Nos comentários, ficou claro que o OP obteve uma resposta vazia. Como o requests.get(url).json()Just Works, o JSON também não está mal formado.
Martijn Pieters
JSONDecodeError: Expecting value: line 1 column 1 (char 0)ocorre especificamente quando uma seqüência vazia é passada para decodificação de json
wesinat0r
JSONDecodeError: Expecting value: line 1 column 1 (char 0)também acontece quando a primeira linha na resposta json é inválida. Exemplo resposta a execução de um az clicomando é ["WARNING: The default kind for created storage account will change to 'StorageV2' from 'Storage' in the future", '{',. Isso me deu o erro que me levou até aqui. O restante da resposta É um objeto json válido. Apenas essa primeira linha quebra as coisas.
SeaDude
34

Com a requestslibJSONDecodeError isso pode ocorrer quando você tem um código de erro http como 404 e tenta analisar a resposta como JSON!

Você deve primeiro verificar se há 200 (OK) ou deixar que isso aconteça com erro para evitar esse caso. Desejo que tenha falhado com uma mensagem de erro menos enigmática.

NOTA : como Martijn Pieters afirmou nos comentários, os servidores podem responder com JSON em caso de erros (depende da implementação), portanto, verificar o Content-Typecabeçalho é mais confiável.

Christophe Roussy
fonte
Desculpe pelo comentário antigo, mas você poderia criar um link para um exemplo? Estou tentando usar minhas habilidades de "executar ação", para "tentar executar ação, retornar resposta, reagir de acordo".
precisa saber é o seguinte
@dcclassics: Exemplo: falha no lado do servidor e o servidor responde mostrando uma página de erro (HTML) em vez de responder com JSON; portanto, o código que analisa a resposta tenta ler JSON, mas falha nas tags HTML.
Christophe Roussy
1
Os servidores podem incluir e incluir corpos JSON em respostas de erro. Não são apenas 200 respostas OK. Você deseja verificar o cabeçalho do tipo de conteúdo.
Martijn Pieters
29

Acho que vale a pena mencionar que, nos casos em que você está analisando o conteúdo de um arquivo JSON - as verificações de sanidade podem ser úteis para garantir que você esteja realmente invocando json.loads()o conteúdo do arquivo, em oposição ao caminho do arquivo JSON :

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

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

Estou um pouco envergonhado em admitir que isso pode acontecer às vezes:

contents = json.loads(json_file_path)
alex
fonte
Bem ... acontece às vezes. Obrigado Funcionou btw.
Sachin Kumar
Eu acho que nesse caso deve-se usar em seu json.load()lugar.
Coddy
13

Verifique o formato de codificação do seu arquivo e use o formato de codificação correspondente ao ler o arquivo. Isso resolverá o seu problema.

with open("AB.json", encoding='utf-8', errors='ignore') as json_data:
     data = json.load(json_data, strict=False)
Ramineni Ravi Teja
fonte
3
Isso funcionou para mim com a pequena mudança de encoding='utf-8', então suponho que às vezes você precise experimentar algumas coisas.
RobertMyles 14/06/19
9

Muitas vezes, isso ocorre porque a string que você está tentando analisar está em branco:

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

Você pode remediar verificando se json_stringestá vazio de antemão:

import json

if json_string:
    x = json.loads(json_string)
else:
    // Your logic here
    x = {}
Alex W
fonte
Enquanto depurava ainda mais no meu código, eu estava chamando response.read()e, em seguida, fiquei consternado quando outra chamada resultou em Expecting value: line 1etc. Removida a instrução de depuração e o problema resolvido.
21419 Joe
Para depurar, você também pode usar este site legal jsonlint.com
Roelant
4

Pode haver 0s incorporados, mesmo depois de chamar decode (). Use 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
fonte
2

Eu tive exatamente esse problema usando solicitações. Agradeço a Christophe Roussy por sua explicação.

Para depurar, usei:

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

Eu estava recebendo uma resposta 404 de volta da API.

Kelsie Braidwood
fonte
1
Pode ser simplificado para response.status_codeou print(response.status_code).
TitanFighter 17/01/19
1

Eu estava tendo o mesmo problema com solicitações (a biblioteca python). Por acaso era o accept-encodingcabeçalho.

Foi definido desta maneira: 'accept-encoding': 'gzip, deflate, br'

Eu simplesmente o removi da solicitação e parei de receber o erro.

Seu Madruga
fonte
1

Para mim, não estava usando autenticação na solicitação.

Neel0507
fonte
1

Para mim, foi o servidor respondendo com algo diferente de 200 e a resposta não foi formatada em json. Acabei fazendo isso antes da análise do 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
FastGTR
fonte
Este foi o problema para mim. O código de status era 500 (erro interno do servidor) em vez de 200, portanto, nenhum json foi retornado e, portanto, não havia nada na linha 1 col 1 do json. Sempre bom verificar se o código de status da solicitação é o que você espera que seja.
thposs 27/02
0

Se você é usuário do Windows, a Tweepy API pode gerar uma linha vazia entre objetos de dados. Devido a essa situação, você pode obter o erro "JSONDecodeError: Expecting value: line 1 column 1 (char 0)". Para evitar esse erro, você pode excluir linhas vazias.

Por exemplo:

 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

Referência: a API de fluxo do Twitter fornece JSONDecodeError ("Expecting value", s, err.value) de None

drorhun
fonte
Não acho que linhas vazias sejam um problema. Ele afirma claramente que o erro está na linha 1 da coluna 1. Acho que essa solução alternativa funciona porque está removendo a BOM do arquivo. Você pode verificar rapidamente: 1. Verifique o tamanho do seu arquivo original (clique com o botão direito do mouse em> Propriedades), pode ser 134.859 bytes 2. Abra o arquivo original com o Notepad ++ 3. Altere a codificação de "UTF-8-BOM" para " UTF-8 ". Salvar 4. Verifique o tamanho novamente. Pode ser 134.856 (3 bytes a menos)
Alex 75
0

Basta verificar se a solicitação possui um código de status 200. Por exemplo:

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

Eu recebi esse erro na resposta de uma API da Web baseada em Python .text, mas ela me levou aqui, então isso pode ajudar outras pessoas com um problema semelhante (é muito difícil filtrar respostas e solicitar problemas em uma pesquisa ao usarrequests ..)

Usando json.dumps()o arg de solicitação data para criar uma string de JSON com escape correto antes do POSTing corrigir o problema para mim

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

Eu encontrei o mesmo problema, enquanto imprimia a string json aberta em um arquivo json, descobri que a string json começa com 'ï »¿', que, ao realizar algumas pesquisas, o arquivo é decodificado por padrão com UTF-8 e alterando a codificação para utf-8-sig, a marcação é removida e carrega o json sem problemas:

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