JSON ValueError: Previsto nome proprietà: riga 1 colonna 2 (char 1)


97

Ho problemi a usare json.loads per convertire in un oggetto dict e non riesco a capire cosa sto facendo di sbagliato.L'errore esatto che ottengo eseguendo questo è

ValueError: Expecting property name: line 1 column 2 (char 1)

Ecco il mio codice:

from kafka.client import KafkaClient
from kafka.consumer import SimpleConsumer
from kafka.producer import SimpleProducer, KeyedProducer
import pymongo
from pymongo import MongoClient
import json

c = MongoClient("54.210.157.57")
db = c.test_database3
collection = db.tweet_col

kafka = KafkaClient("54.210.157.57:9092")

consumer = SimpleConsumer(kafka,"myconsumer","test")
for tweet in consumer:
    print tweet.message.value
    jsonTweet=json.loads(({u'favorited': False, u'contributors': None})
    collection.insert(jsonTweet)

Sono abbastanza sicuro che l'errore si sia verificato nella penultima riga

jsonTweet=json.loads({u'favorited': False, u'contributors': None})

ma non so cosa fare per risolverlo. Tutto il consiglio sarebbe apprezzato.


3
vedi un errore di sintassi lì? Un randagio "è un errore di copia incolla?
karthikr

Qual è stata la stringa JSON stampata dalla riga print tweet.message.value?
Luke Woodward

1
Il ValueErrorè trasmette a causa di un errore nel ingresso JSON, non è un problema nel codice. (A parte il mancante "che dovrebbe normalmente inviare un SyntaxErrorquindi presumo sia solo un errore di copia incolla.)
Cld

(A proposito, utf_8 è la codifica predefinita per json.loads, quindi non è necessario indicarlo.)
Cld

Grazie per l'input. Modificata la domanda, dovrebbe essere più chiara ora.
dredbound

Risposte:


83

json.loadscaricherà una stringa json in un python dict, json.dumpsscaricherà un python dictin una stringa json, ad esempio:

>>> json_string = '{"favorited": false, "contributors": null}'
'{"favorited": false, "contributors": null}'
>>> value = json.loads(json_string)
{u'favorited': False, u'contributors': None}
>>> json_dump = json.dumps(value)
'{"favorited": false, "contributors": null}'

Quindi quella riga non è corretta poiché stai provando a loadun Python dict, e ti json.loadsaspetti un valido json stringche dovrebbe avere<type 'str'> .

Quindi, se stai provando a caricare il json, dovresti cambiare ciò che stai caricando in modo che assomigli al file json_string sopra, o dovresti scaricarlo. Questa è solo la mia ipotesi migliore dalle informazioni fornite. Cosa stai cercando di ottenere?

Inoltre non è necessario specificare la uprima delle stringhe, come @Cld menzionato nei commenti.


2
json.loads caricherà un -> oggetto json <- in un dict python - Questo è contrario a ciò che dicono i documenti e anche a ciò che fa il tuo codice - stai usando load () su una stringa, non un json oggetto .
7stud

Sì @ 7stud, hai ragione, sta caricando una stringa. Ma deve essere una stringa json valida. Ho aggiornato la mia risposta.
Yep_It's_Me

186

Ho riscontrato un altro problema che restituisce lo stesso errore.

Emissione di virgolette singole

Ho usato una stringa json con virgolette singole :

{
    'property': 1
}

Ma json.loadsaccetta solo virgolette doppie per le proprietà json :

{
    "property": 1
}

Problema con la virgola finale

json.loads non accetta una virgola finale:

{
  "property": "text", 
  "property2": "text2",
}

Soluzione: astper risolvere problemi con virgolette singole e virgole finali

Puoi usare ast (parte della libreria standard sia per Python 2 che per 3) per questa elaborazione. Ecco un esempio:

import ast
# ast.literal_eval() return a dict object, we must use json.dumps to get JSON string
import json

# Single quote to double with ast.literal_eval()
json_data = "{'property': 'text'}"
json_data = ast.literal_eval(json_data)
print(json.dumps(json_data))
# Displays : {"property": "text"}

# ast.literal_eval() with double quotes
json_data = '{"property": "text"}'
json_data = ast.literal_eval(json_data)
print(json.dumps(json_data))
# Displays : {"property": "text"}

# ast.literal_eval() with final coma
json_data = "{'property': 'text', 'property2': 'text2',}"
json_data = ast.literal_eval(json_data)
print(json.dumps(json_data))
# Displays : {"property2": "text2", "property": "text"}

Utilizzando ast ti impedirà di problemi con virgolette singole e virgole finali interpretando il dizionario JSON come Python (quindi devi seguire la sintassi del dizionario Python). È un'alternativa di eval()funzione abbastanza buona e sicura per le strutture letterali.

Documentazione Python ci ha avvertito dell'utilizzo di stringhe grandi / complesse:

Avvertimento È possibile bloccare l'interprete Python con una stringa sufficientemente grande / complessa a causa dei limiti di profondità dello stack nel compilatore AST di Python.

json.dumps con virgolette singole

Per usare json.dumpsfacilmente le virgolette singole puoi usare questo codice:

import ast
import json

data = json.dumps(ast.literal_eval(json_data_single_quote))

ast documentazione

ast Python 3 doc

ast Python 2 doc

Attrezzo

Se modifichi spesso JSON, puoi utilizzare CodeBeautify . Ti aiuta a correggere l'errore di sintassi e minimizzare / abbellire JSON.

Spero possa essere d'aiuto.


10
  1. sostituire tutte le virgolette singole con virgolette doppie
  2. sostituisci 'u "' dalle tue stringhe a '"' ... quindi sostanzialmente converti gli unicode interni in stringhe prima di caricare la stringa in json
>> strs = "{u'key':u'val'}"
>> strs = strs.replace("'",'"')
>> json.loads(strs.replace('u"','"'))

1
un modo più pitonico sarebbe usare ast.literal_eval ("{u'key ': u'val'}"). Si prenderà cura di tutti i problemi relativi al formato
Vinay Pande

json.loads (strs.replace ('u "', '')) non funziona. Di seguito è riportato l'errore Traceback (la chiamata più recente per ultima): File" <stdin> ", riga 1, in <module> File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/__init__.py", riga 338, nei caricamenti return _default_decoder.decode (s) obj, end = self.scan_once (s , idx) ValueError: Previsto nome proprietà: riga 1 colonna 2 (char 1)
Sanjay Pradeep

4

Tutte le altre risposte potrebbero rispondere alla tua domanda, ma ho affrontato lo stesso problema dovuto al randagio ,che ho aggiunto alla fine della mia stringa json in questo modo:

{
 "key":"123sdf",
 "bus_number":"asd234sdf",
}

Finalmente ho funzionato quando ho rimosso extra ,come questo:

{
 "key":"123sdf",
 "bus_number":"asd234sdf"
}

Spero che questo aiuto! Saluti.


1
buono, anche se questo è già coperto dalla risposta di
jedema

@fedorqui Quella parte è stata aggiunta dopo la mia risposta ( stackoverflow.com/posts/36599122/revisions ) Ora, potresti dare un +1 :)
Rishabh Agrahari

1
oh, hai ragione! È stato aggiunto da gennaio 2018. Si scusa e +1 :)
fedorqui "SO stop harming"

0

usato ast, esempio

In [15]: a = "[{'start_city': '1', 'end_city': 'aaa', 'number': 1},\
...:      {'start_city': '2', 'end_city': 'bbb', 'number': 1},\
...:      {'start_city': '3', 'end_city': 'ccc', 'number': 1}]"
In [16]: import ast
In [17]: ast.literal_eval(a)
Out[17]:
[{'end_city': 'aaa', 'number': 1, 'start_city': '1'},
 {'end_city': 'bbb', 'number': 1, 'start_city': '2'},
 {'end_city': 'ccc', 'number': 1, 'start_city': '3'}]

0

Un altro caso in cui ho riscontrato questo è stato quando stavo usando echoper convogliare il JSON nel mio script python e incautamente avvolto la stringa JSON tra virgolette doppie:

echo "{"thumbnailWidth": 640}" | myscript.py

Nota che la stringa JSON stessa ha virgolette e avrei dovuto fare:

echo '{"thumbnailWidth": 640}' | myscript.py

Come è stato, questo è ciò che lo script python ricevuto: {thumbnailWidth: 640}; le doppie virgolette sono state effettivamente rimosse.

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.