JSON ValueError: Erwarteter Eigenschaftsname: Zeile 1, Spalte 2 (Zeichen 1)

97

Ich habe Probleme mit der Verwendung von json.loads zum Konvertieren in ein Diktierobjekt und kann nicht herausfinden, was ich falsch mache. Der genaue Fehler, den ich beim Ausführen bekomme, ist

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

Hier ist mein Code:

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)

Ich bin mir ziemlich sicher, dass der Fehler in der vorletzten Zeile auftritt

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

aber ich weiß nicht, was ich tun soll, um das Problem zu beheben. Jeder Rat wäre dankbar.

dredbound
quelle
3
sehen Sie dort einen Syntaxfehler? Ein Streuner "ist das ein Kopier- und Einfügefehler?
Karthikr
Was war die JSON-Zeichenfolge, die von der Zeile ausgedruckt wurde print tweet.message.value?
Luke Woodward
1
Das ValueErrorwird aufgrund eines Fehlers in der JSON-Eingabe gesendet, kein Problem in Ihrem Code. (Abgesehen von den Vermissten ", die normalerweise eine senden sollten, SyntaxError
gehe
(Übrigens ist utf_8 die Standardcodierung für json.loads und muss daher nicht angegeben werden.)
Cld
Danke für die Eingabe. Die Frage bearbeitet, sollte jetzt klarer sein.
Dredbound

Antworten:

83

json.loadslädt einen JSON-String in eine Python dict, json.dumpsspeichert einen Python dictin einen JSON-String, zum Beispiel:

>>> 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}'

Diese Zeile ist also falsch, da Sie versuchen, loadeine Python zu verwenden dict, und json.loadseine gültige Zeile erwartet, json stringdie vorhanden sein sollte <type 'str'>.

Wenn Sie also versuchen, den JSON zu laden, sollten Sie das, was Sie laden, so ändern, dass es wie json_stringoben aussieht , oder Sie sollten es ausgeben. Dies ist nur meine beste Vermutung aus den gegebenen Informationen. Was versuchen Sie zu erreichen?

Außerdem müssen Sie die uZeichenfolgen nicht vor Ihren Zeichenfolgen angeben , wie @Cld in den Kommentaren erwähnt.

Yep_It's_Me
quelle
2
json.loads lädt ein -> json-Objekt <- in ein Python-Diktat. - Dies steht im Widerspruch zu den Aussagen der Dokumente und sogar zu dem, was Ihr eigener Code tut. Sie verwenden load () für eine Zeichenfolge, nicht für einen json Objekt .
7stud
Ja @ 7stud, Sie haben Recht, es wird eine Zeichenfolge geladen. Es muss jedoch eine gültige JSON-Zeichenfolge sein. Ich habe meine Antwort aktualisiert.
Yep_It's_Me
186

Ich habe ein anderes Problem festgestellt, das denselben Fehler zurückgibt.

Ausgabe mit einfachem Angebot

Ich habe einen JSON-String mit einfachen Anführungszeichen verwendet :

{
    'property': 1
}

Aber json.loadsakzeptiert nur doppelte Anführungszeichen für json Eigenschaften :

{
    "property": 1
}

Letzte Komma-Ausgabe

json.loads akzeptiert kein abschließendes Komma:

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

Lösung: astLösen von Problemen mit einfachen Anführungszeichen und endgültigen Kommas

Sie können ast(Teil der Standardbibliothek für Python 2 und 3) für diese Verarbeitung verwenden. Hier ist ein Beispiel :

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"}

Verwenden von ast die können Sie Probleme mit einfachen Anführungszeichen und endgültigen Kommas vermeiden, indem Sie das JSON wie das Python-Wörterbuch interpetieren (Sie müssen also die Python-Wörterbuchsyntax befolgen). Es ist eine ziemlich gute und sichere eval()Funktionsalternative für wörtliche Strukturen.

Python-Dokumentation warnte uns vor der Verwendung großer / komplexer Zeichenfolgen:

Warnung Aufgrund von Einschränkungen der Stapeltiefe im AST-Compiler von Python ist es möglich, den Python-Interpreter mit einer ausreichend großen / komplexen Zeichenfolge zum Absturz zu bringen.

json.dumps mit einfachen Anführungszeichen

Um es json.dumpseinfach mit einfachen Anführungszeichen zu verwenden, können Sie diesen Code verwenden:

import ast
import json

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

ast Dokumentation

ast Python 3 doc

ast Python 2 doc

Werkzeug

Wenn Sie JSON häufig bearbeiten, können Sie CodeBeautify verwenden . Es hilft Ihnen, Syntaxfehler zu beheben und JSON zu minimieren / zu verschönern.

Ich hoffe, es hilft.

Samuel Dauzon
quelle
10
  1. Ersetzen Sie alle einfachen Anführungszeichen durch doppelte Anführungszeichen
  2. Ersetzen Sie 'u "' von Ihren Zeichenfolgen durch '"' ... konvertieren Sie also im Grunde interne Unicodes in Zeichenfolgen, bevor Sie die Zeichenfolge in json laden
>> strs = "{u'key':u'val'}"
>> strs = strs.replace("'",'"')
>> json.loads(strs.replace('u"','"'))
Vinay Pande
quelle
1
Ein pythonischerer Weg wäre, ast.literal_eval ("{u'key ': u'val'}") zu verwenden. Es wird sich um alle Formatprobleme kümmern
Vinay Pande
json.loads (strs.replace ('u "', '')) funktioniert nicht. Hier ist der folgende Fehler, Traceback (letzter Aufruf zuletzt): Datei" <stdin> ", Zeile 1, in der Datei <module> "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/__init__.py", Zeile 338, gibt beim Laden _default_decoder.decode (s) obj, end = self.scan_once (s) zurück , idx) ValueError: Erwarteter Eigenschaftsname: Zeile 1 Spalte 2 (Zeichen 1)
Sanjay Pradeep
4

Alle anderen Antworten beantworten möglicherweise Ihre Frage, aber ich hatte das gleiche Problem, das auf Streu zurückzuführen war, ,das ich am Ende meiner JSON-Zeichenfolge wie folgt hinzugefügt habe:

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

Ich habe es endlich zum Laufen gebracht, als ich extra ,so entfernt habe:

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

Ich hoffe das hilft! Prost.

Rishabh Agrahari
quelle
1
gut, obwohl dies bereits durch die Antwort
fedorqui 'SO hör auf,'
@fedorqui Dieser Teil wurde nach meiner Antwort hinzugefügt ( stackoverflow.com/posts/36599122/revisions ) Nun möchten Sie vielleicht eine +1 geben :)
Rishabh Agrahari
1
Oh, du hast recht! Es wurde von Jan 2018 hinzugefügt. Entschuldigt sich und +1 :)
fedorqui 'SO hör auf,'
0

verwendet ast, Beispiel

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'}]
xin.chen
quelle
0

Ein anderer Fall, in dem ich darauf gestoßen bin, war, als ich echoden JSON in mein Python-Skript leitete und den JSON-String achtlos in doppelte Anführungszeichen setzte:

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

Beachten Sie, dass die JSON-Zeichenfolge selbst Anführungszeichen enthält, und ich hätte Folgendes tun sollen:

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

So wie es war, erhielt das Python-Skript Folgendes : {thumbnailWidth: 640}; Die doppelten Anführungszeichen wurden effektiv entfernt.

Jim Hoagland
quelle