JSON ValueError: Özellik adı bekleniyor: satır 1 sütun 2 (karakter 1)


97

Bir dict nesnesine dönüştürmek için json.loads kullanırken sorun yaşıyorum ve neyi yanlış yaptığımı anlayamıyorum. Bunu çalıştırdığım tam hata

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

İşte kodum:

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)

Hatanın 2. satırdan son satıra kadar oluştuğundan oldukça eminim

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

ama düzeltmek için ne yapacağımı bilmiyorum. Herhangi bir tavsiye memnuniyetle karşılanacaktır.


3
orada bir sözdizimi hatası görüyor musunuz? Başıboş "bir kopyala yapıştır hatası mı?
karthikr

Satır tarafından yazdırılan JSON dizisi neydi print tweet.message.value?
Luke Woodward

1
ValueErrorÇünkü JSON girişi, kodunuzda değil sorunun bir hata nedeniyle göndermek edilir. ( "Normalde göndermesi gereken eksiklerin yanında, SyntaxErrorbunun sadece bir kopyala yapıştır hatası olduğunu varsayıyorum.)
Cld

(Bu arada, utf_8 json.loads için varsayılan kodlamadır, bu yüzden bunu belirtmesi gerekmez.)
Cld

Giriş için teşekkürler. Soru düzenlendi, şimdi daha net olmalı.
dredbound

Yanıtlar:


84

json.loads bir python'a bir json dizesi yükleyecek dict , json.dumpsbir piton dökümü olacaktır dictörneğin bir json dizeye:

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

Yani bu satır yanlış, çünkü load bir pythondict ve sahip olması gereken json.loadsbir geçerli bekliyorsunuz .json string<type 'str'>

Dolayısıyla, json'u yüklemeye çalışıyorsanız, yüklediğiniz şeyi json_stringyukarıdakine benzeyecek şekilde değiştirmelisiniz, ya da damping yapmalısınız. Bu, verilen bilgilerden en iyi tahminim. Başarmaya çalıştığınız şey nedir?

Ayrıca uyorumlarda belirtildiği gibi, dizelerinizden önce belirtmenize gerek yoktur .


2
json.loads bir -> json nesnesini <- bir python diktesine yükleyecektir - Bu, belgelerin söylediklerinin ve hatta kendi kodunuzun yaptığı şeyin aksine - bir dizede json değil, load () kullanıyorsunuz nesne .
7stud

Evet @ 7stud, haklısınız, bir dize yükleniyor. Ancak geçerli bir json dizesi olmalıdır. Cevabımı güncelledim.
Yep_It's_Me

191

Aynı hatayı döndüren başka bir sorunla karşılaştım.

Tek tırnak sorunu

Tek tırnaklı bir json dizesi kullandım :

{
    'property': 1
}

Ancak json.loadsjson özellikleri için yalnızca çift tırnak kabul eder :

{
    "property": 1
}

Son virgül sorunu

json.loads son bir virgül kabul etmez:

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

Çözüm: ast Tek tırnak ve son virgül sorunlarını çözmek için

Bu işlem için ast(hem Python 2 hem de 3 için standart kitaplığın bir parçası) kullanabilirsiniz . İşte bir örnek :

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

Kullanımı ast, JSON'u Python diksiyonu gibi araya yazarak tek tırnak ve son virgül sorunlarını önleyecektir (bu nedenle Python diksiyon sözdizimini izlemelisiniz). Oldukça iyi ve güvenli bir alternatifeval()Gerçek yapılar için işlev .

Python belgeleri bizi büyük / karmaşık dizge kullanma konusunda uyardı:

Uyarı Python'un AST derleyicisindeki yığın derinliği sınırlamaları nedeniyle Python yorumlayıcısını yeterince büyük / karmaşık bir dizeyle çökertmek mümkündür.

Tek tırnaklı json.dumps

Kullanmak için json.dumpstek tırnak ile kolayca bu kodu kullanabilirsiniz:

import ast
import json

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

ast dokümantasyon

ast Python 3 doc

ast Python 2 belgesi

Araç

JSON'u sık sık düzenliyorsanız, CodeBeautify'ı kullanabilirsiniz . Sözdizimi hatasını düzeltmenize ve JSON'u küçültmenize / güzelleştirmenize yardımcı olur.

Umut ediyorum bu yardım eder.


10
  1. tüm tek tırnakları çift tırnakla değiştirin
  2. Dizelerinizdeki 'u "' yerine '"' ... bu yüzden temelde dizeyi json'a yüklemeden önce dahili unicod'ları dizelere dönüştürün
>> strs = "{u'key':u'val'}"
>> strs = strs.replace("'",'"')
>> json.loads(strs.replace('u"','"'))

1
daha fazla pitonik yol ast.literal_eval ("{u'key ': u'val'}") kullanmak olacaktır.
Biçimle

json.loads (strs.replace ('u "', '')) çalışmıyor. İşte aşağıdaki hata: Traceback (en son çağrı son): Dosya" <stdin> ", satır 1, <module> Dosyasında "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/__init__.py", satır 338, yüklerde _default_decoder.decode (s) obj, end = self.scan_once (s , idx) ValueError: Özellik adı bekleniyor: satır 1 sütun 2 (karakter 1)
Sanjay Pradeep

4

Diğer tüm cevaplar sorgunuza cevap verebilir, ancak ,json dizgimin sonuna şu şekilde eklediğim başıboşluk nedeniyle aynı sorunla karşılaştım :

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

Sonunda böyle fazlalıkları kaldırdığımda çalıştırdım ,:

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

Umarım bu yardımcı olur! şerefe.



@fedorqui Cevabımdan sonra bu kısım eklendi ( stackoverflow.com/posts/36599122/revisions ) Şimdi, +1 vermek isteyebilirsiniz :)
Rishabh Agrahari

1
oh, haklısın! Ocak 2018 tarafından eklendi. Özür diler ve +1 :)
fedorqui 'SO zarar vermeyi bırak'

0

ast kullanıldı, örnek

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

Bununla karşılaştığım farklı bir durum echo, JSON'u python betiğime yönlendirmek için kullandığım ve JSON dizesini dikkatsizce çift tırnak içine sardığım zamandı :

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

JSON dizesinin kendisinin tırnak işaretlerine sahip olduğunu ve şunu yapmam gerektiğini unutmayın:

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

Olduğu gibi, python betiğinin aldığı buydu {thumbnailWidth: 640}:; çift ​​tırnaklar etkili bir şekilde kaldırıldı.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.