web-dev-qa-db-ja.com

JSON ValueError:期待されるプロパティ名:1行2列(char 1)

私は辞書オブジェクトに変換するためにjson.loadsを使用することに問題があります、そして私は私が間違っていることを理解することができません。

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

これが私のコードです:

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)

最後の2行目から2行目でエラーが発生していると確信しています

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

しかし、私はそれを修正するために何をすべきかわかりません。何かアドバイスがあれば幸いです。

79
dredbound

json.loadsはjson文字列をpythonのdictにロードし、json.dumpsはpythonのdictをjsonの文字列にダンプします。次に例を示します。

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

Pythonのloaddictにしようとしているので、その行は正しくなく、json.loadsjson stringを持つべき有効な<type 'str'>を期待しています。

あなたがJSONをロードしようとしているのであれば、あなたは上記のjson_stringのようにロードするものを変更する必要があります、またはあなたはそれをダンプする必要があります。これは与えられた情報からの私の最も良い推測です。あなたが達成しようとしていることは何ですか?

コメントで@Cldが述べたように、あなたはあなたの文字列の前にuを指定する必要もありません。

74
Yep_It's_Me

同じエラーを返す別の問題が発生しました。

一重引用符の問題

私は一重引用符でJSON文字列を使用しました。

{
    'property': 1
}

しかし、json.loadsはjsonプロパティに対して二重引用符だけを受け入れます

{
    "property": 1
}

最後のカンマ号

json.loadsは最後のカンマを受け付けません。

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

解決策:一重引用符と最後のカンマの問題を解決するためのast

この処理にはast(Python 2と3の両方の標準ライブラリの一部)を使用できます。これが一例です。

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

astを使用すると、Pythonの辞書のようにJSONを混在させることで、一重引用符や最後のカンマの問題を防ぐことができます(したがって、Pythonの辞書の構文に従う必要があります)。これはリテラル構造体のためのeval()関数のかなり良いそして安全な代替案です。

Pythonドキュメント 大きな文字列や複素数文字列を使うように警告されました。

警告PythonのASTコンパイラのスタック深度の制限により、十分に大きい/複雑な文字列でPythonインタプリタをクラッシュさせる可能性があります。

一重引用符付きのjson.dumps

json.dumpsを一重引用符で簡単に使用するには、次のコードを使用します。

import ast
import json

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

astのドキュメント

Python 3 docから

ast 2 Python

ツール

頻繁にJSONを編集する場合は、 CodeBeautify を使用することができます。それはあなたが構文エラーを修正し、JSONを縮小/美化するのを助けます。

助けになれば幸いです。

149
jedema
  1. すべての一重引用符を二重引用符で置き換えます
  2. あなたの文字列の 'u "'を '"'に置き換えてください。基本的にjsonに文字列をロードする前に内部のUnicodeを文字列に変換します
>> strs = "{u'key':u'val'}"
>> strs = strs.replace("'",'"')
>> json.loads(strs.replace('u"','"'))
7
Vinay Pande

他のすべての答えがあなたの質問に答えるかもしれませんが、私はこのように私のJSON文字列の最後に追加した,の浮遊による同じ問題に直面しました:

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

このように余分な,を削除したとき、ついに私はそれがうまくいったようになりました:

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

この助けを願っています!乾杯。

3

astを使った例

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
xin.chen