JSON ValueError: ожидание имени свойства: строка 1 столбец 2 (char 1)
У меня возникли проблемы с использованием json.loads для преобразования в объект dict, и я не могу понять, что я делаю неправильно.
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-й до последней строки
jsonTweet=json.loads({u'favorited': False, u'contributors': None})
но я не знаю, что делать, чтобы это исправить. Любой совет будет принят во внимание.
Ответы
Ответ 1
json.loads
загрузит JSon строку в питона dict
, json.dumps
сбросит питон 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}'
Так что эта строка неверна, так как вы пытаетесь load
python dict
, а json.loads
ожидает допустимой json string
которая должна иметь <type 'str'>
.
Так что, если вы пытаетесь загрузить json, вы должны изменить то, что вы загружаете, чтобы оно выглядело как json_string
выше, или вы должны json_string
его. Это только мое лучшее предположение из приведенной информации. Что вы пытаетесь достичь?
Также вам не нужно указывать u
перед строками, как @Cld упомянул в комментариях.
Ответ 2
Я столкнулся с другой проблемой, которая возвращает ту же ошибку.
Одиночная кавычка
Я использовал строку 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
предотвратит проблемы с одинарными кавычками и заключительными запятыми, если использовать JSON, как словарь Python (поэтому вы должны следовать синтаксису словаря Python). Это довольно хорошая и безопасная альтернатива функции eval()
для литеральных структур.
Документация Python предупреждает нас об использовании большой/сложной строки:
Предупреждение. Возможен сбой интерпретатора Python с достаточно большой/сложной строкой из-за ограничений глубины стека в компиляторе Pythons AST.
json.dumps с одинарными кавычками
Чтобы json.dumps
использовать json.dumps
с одинарными кавычками, вы можете использовать этот код:
import ast
import json
data = json.dumps(ast.literal_eval(json_data_single_quote))
ast
документация
Ast Python 3 док
Ast Python 2 док
Инструмент
Если вы часто редактируете JSON, вы можете использовать CodeBeautify. Это поможет вам исправить синтаксическую ошибку и минимизировать/украсить JSON.
Я надеюсь, что это помогает.
Ответ 3
- заменить все одинарные кавычки на двойные
- замените 'u "' из ваших строк на '"'... так что в основном конвертируйте внутренние юникоды в строки перед загрузкой строки в json
>> strs = "{u'key':u'val'}"
>> strs = strs.replace("'",'"')
>> json.loads(strs.replace('u"','"'))
Ответ 4
Все остальные ответы могут ответить на ваш запрос, но я столкнулся с той же проблемой, которая возникла из-за блуждающего ,
, который я добавил в конце моей строки json следующим образом:
{
"key":"123sdf",
"bus_number":"asd234sdf",
}
Наконец-то я получил его, когда я удалил лишний ,
следующим образом:
{
"key":"123sdf",
"bus_number":"asd234sdf"
}
Надеюсь, что эта помощь! веселит.
Ответ 5
использовали 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'}]