JSON ValueError: ожидаемое имя свойства: строка 1 столбец 2 (символ 1)

97

У меня проблемы с использованием 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)

Я почти уверен, что ошибка возникает на второй и последней строке

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

но я не знаю, что делать, чтобы это исправить. Любой совет будет принят во внимание.

dredbound
источник
3
вы видите там синтаксическую ошибку? Причина в "том, что ошибка копирования и вставки?
karthikr
Какая строка JSON была напечатана строкой print tweet.message.value?
Люк Вудворд
1
Это ValueErrorотправлено из-за ошибки во вводе JSON, а не из-за проблемы в вашем коде. (Помимо пропавших без вести, "кто обычно должен отправлять, SyntaxErrorпоэтому я предполагаю, что это просто ошибка копирования и вставки.)
Cld
(Между прочим, utf_8 - это кодировка по умолчанию для json.loads, поэтому указывать ее не нужно.)
Cld,
Спасибо за вклад. Отредактировал вопрос, теперь должно быть понятнее.
dredbound

Ответы:

84

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выше, или вы должны сбросить его. Это всего лишь мое предположение из предоставленной информации. Чего вы пытаетесь достичь?

Также не нужно указывать u перед строками, как @Cld упоминается в комментариях.

Yep_It's_Me
источник
2
json.loads загрузит -> json object <- в python dict - это противоречит тому, что говорят документы, и даже тому, что делает ваш собственный код - вы используете load () в строке, а не json объект .
7stud
Да @ 7stud, ты прав, он загружает строку. Но это должна быть действительная строка json. Я обновил свой ответ.
Yep_It's_Me
187

Я столкнулся с другой проблемой, которая возвращает ту же ошибку.

Проблема с одинарной цитатой

Я использовал строку 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 с достаточно большой / сложной строкой из-за ограничений глубины стека в компиляторе Python AST.

json.dumps в одинарных кавычках

Чтобы json.dumpsлегко использовать одинарные кавычки, вы можете использовать этот код:

import ast
import json

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

ast документация

аст Python 3 документ

аст Python 2 документ

Инструмент

Если вы часто редактируете JSON, вы можете использовать CodeBeautify . Это поможет вам исправить синтаксическую ошибку и минимизировать / украсить JSON.

Я надеюсь, что это помогает.

Самуэль Даузон
источник
10
  1. заменить все одинарные кавычки двойными кавычками
  2. замените 'u "' из ваших строк на '"' ... так что в основном преобразуйте внутренние юникоды в строки перед загрузкой строки в json
>> strs = "{u'key':u'val'}"
>> strs = strs.replace("'",'"')
>> json.loads(strs.replace('u"','"'))
Винай Панде
источник
1
более питоническим способом было бы использовать ast.literal_eval ("{u'key ': u'val'}"). Он позаботится обо всех проблемах, связанных с форматом
Vinay
json.loads (strs.replace ('u "', '')) не работает. Ниже приведена ошибка Traceback (последний вызов последнего): файл" <stdin> ", строка 1, в файле <module> "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/__init__.py", строка 338, при загрузке возвращает _default_decoder.decode (s) obj, end = self.scan_once (s , idx) ValueError: Ожидается имя свойства: строка 1 столбец 2 (символ 1)
Санджай Прадип
4

Все остальные ответы могут отвечать на ваш запрос, но я столкнулся с той же проблемой, которая была связана с ошибкой, ,которую я добавил в конце моей строки json следующим образом:

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

Наконец-то он заработал, когда удалил лишнее ,:

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

Надеюсь на эту помощь! ура.

Ришаб Аграхари
источник
1
хорошо, хотя это уже покрыто ответом
jedema
@fedorqui Эта часть была добавлена ​​после моего ответа ( stackoverflow.com/posts/36599122/revisions ) Теперь вы можете
поставить
1
ах ты прав! Он был добавлен в январе 2018 года.
Приносит
0

используется как, например

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
источник
0

Другой случай, когда я столкнулся с этим, был, когда я использовал echoдля передачи JSON в свой скрипт python и небрежно заключил строку JSON в двойные кавычки:

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

Обратите внимание, что в самой строке JSON есть кавычки, и я должен был сделать:

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

Как это было, это то , что получил сценарий питона: {thumbnailWidth: 640}; двойные кавычки были удалены.

Джим Хоугланд
источник