JSON ValueError: Mengharapkan nama properti: baris 1 kolom 2 (karakter 1)

97

Saya mengalami masalah dalam menggunakan json.loads untuk mengonversi ke objek dict dan saya tidak tahu apa yang saya lakukan salah.

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

Ini kode saya:

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)

Saya cukup yakin bahwa kesalahan terjadi pada baris ke-2 hingga terakhir

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

tapi saya tidak tahu harus berbuat apa untuk memperbaikinya. Nasihat apa pun akan dihargai.

dikeruk
sumber
3
apakah Anda melihat kesalahan sintaks di sana? Apakah "itu kesalahan salin tempel?
karthikr
Apa string JSON yang dicetak oleh baris print tweet.message.value?
Luke Woodward
1
The ValueErroradalah mengirim karena kesalahan dalam input JSON, bukan masalah dalam kode Anda. (Selain yang hilang "yang biasanya harus mengirim SyntaxErrorjadi saya anggap itu hanya kesalahan salin tempel.)
Cld
(Omong-omong, utf_8 adalah pengkodean default untuk json.loads jadi tidak perlu mengindikasikannya.)
Cld
Terima kasih atas masukannya. Pertanyaan yang diedit, harus lebih jelas sekarang.
ditarik

Jawaban:

83

json.loadsakan memuat string json ke dalam python dict, json.dumpsakan membuang python dictke string json, misalnya:

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

Jadi baris itu salah karena Anda mencoba loadpython dict, dan json.loadsmengharapkan valid json stringyang seharusnya ada <type 'str'>.

Jadi jika Anda mencoba memuat json, Anda harus mengubah apa yang Anda muat agar terlihat seperti di json_stringatas, atau Anda harus membuangnya. Ini hanya tebakan terbaik saya dari informasi yang diberikan. Apa yang ingin Anda capai?

Anda juga tidak perlu menentukan usebelum string Anda, seperti yang disebutkan @Cld di komentar.

Ya_itu_Me
sumber
2
json.loads akan memuat -> objek json <- ke dalam python dict - Itu bertentangan dengan apa yang dikatakan oleh dokumen dan bahkan apa yang dilakukan kode Anda sendiri - Anda menggunakan load () pada string, bukan json objek .
7stud
Ya @ 7stud, Anda benar, ini sedang memuat string. Tapi itu harus berupa string json yang valid. Saya telah memperbarui jawaban saya.
Ya_itu_Me
186

Saya mengalami masalah lain yang mengembalikan kesalahan yang sama.

Masalah kutipan tunggal

Saya menggunakan string json dengan tanda kutip tunggal :

{
    'property': 1
}

Tetapi json.loadshanya menerima tanda kutip ganda untuk properti json :

{
    "property": 1
}

Masalah koma terakhir

json.loads tidak menerima koma terakhir:

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

Solusi: astuntuk menyelesaikan masalah kutipan tunggal dan koma terakhir

Anda dapat menggunakan ast(bagian dari pustaka standar untuk Python 2 dan 3) untuk pemrosesan ini. Berikut ini contohnya:

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

Menggunakan astakan mencegah Anda dari kutipan tunggal dan masalah koma terakhir dengan menafsirkan JSON seperti kamus Python (jadi Anda harus mengikuti sintaks kamus Python). Ini adalah alternatif eval()fungsi yang cukup bagus dan aman untuk struktur literal.

Dokumentasi Python memperingatkan kita untuk menggunakan string besar / kompleks:

Peringatan Ada kemungkinan untuk crash interpreter Python dengan string yang cukup besar / kompleks karena batasan kedalaman tumpukan dalam kompilator AST Python.

json.dumps dengan tanda kutip tunggal

Untuk menggunakan json.dumpsdengan tanda kutip tunggal dengan mudah Anda dapat menggunakan kode ini:

import ast
import json

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

ast dokumentasi

ast Python 3 dokumen

ast Python 2 dokumen

Alat

Jika Anda sering mengedit JSON, Anda dapat menggunakan CodeBeautify . Ini membantu Anda memperbaiki kesalahan sintaks dan meminimalkan / mempercantik JSON.

Saya harap ini membantu.

Samuel Dauzon
sumber
10
  1. ganti semua tanda kutip tunggal dengan tanda kutip ganda
  2. ganti 'u "' dari string Anda ke '"' ... jadi pada dasarnya ubah unicode internal menjadi string sebelum memuat string ke json
>> strs = "{u'key':u'val'}"
>> strs = strs.replace("'",'"')
>> json.loads(strs.replace('u"','"'))
Vinay Pande
sumber
1
cara yang lebih pythonic adalah dengan menggunakan ast.literal_eval ("{u'key ': u'val'}"). Ini akan menangani semua masalah terkait format
Vinay Pande
json.loads (strs.replace ('u "', '')) tidak berfungsi. Berikut adalah kesalahan di bawah ini, Traceback (panggilan terakhir terakhir): File" <stdin> ", baris 1, di <module> File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/__init__.py", baris 338, dalam pemuatan kembali _default_decoder.decode (s) obj, end = self.scan_once (s) , idx) ValueError: Nama properti yang diharapkan: baris 1 kolom 2 (karakter 1)
Sanjay Pradeep
4

Semua jawaban lain dapat menjawab pertanyaan Anda, tetapi saya menghadapi masalah yang sama yang disebabkan oleh nyasar ,yang saya tambahkan di akhir string json saya seperti ini:

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

Saya akhirnya berhasil saat saya menghapus ekstra ,seperti ini:

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

Semoga bantuan ini! Bersulang.

Rishabh Agrahari
sumber
1
bagus, meski sudah tercakup dalam jawaban
jedema
@fedorqui Bagian itu ditambahkan setelah jawaban saya ( stackoverflow.com/posts/36599122/revisions ) Sekarang, Anda mungkin ingin memberi +1 :)
Rishabh Agrahari
1
oh kamu benar Itu ditambahkan oleh Jan 2018. Minta maaf dan +1 :)
fedorqui 'SO stop harming'
0

digunakan ast, contoh

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

Kasus berbeda yang saya temui adalah ketika saya menggunakan echountuk menyalurkan JSON ke skrip python saya dan secara sembarangan membungkus string JSON dalam tanda kutip ganda:

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

Perhatikan bahwa string JSON itu sendiri memiliki tanda kutip dan saya harus melakukannya:

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

Seperti itu, ini adalah apa script python yang diterima: {thumbnailWidth: 640}; tanda kutip ganda secara efektif dihapus.

Jim Hoagland
sumber