JSON ValueError: Очікує назву властивості: рядок 1, стовпець 2 (char 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)

Я майже впевнений, що помилка трапляється з 2-го до останнього рядка

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

але я не знаю, що робити, щоб це виправити. Будь-яка порада буде вдячна.


3
ви бачите там синтаксичну помилку? Бродячим "є те, що помилка вставлення копії?
karthikr

Якою лінією було надруковано рядок JSON print tweet.message.value?
Люк Вудвард

1
Передача ValueErrorпередачі через помилку у вході JSON, а не проблема у вашому коді. (Окрім зниклих, "які зазвичай повинні надсилати повідомлення, SyntaxErrorтому я припускаю, що це лише помилка копіювання).
Cld

(До речі, utf_8 - це кодування за замовчуванням для json.loads, тому його не потрібно вказувати.)
Cld

Дякуємо за вклад. Відредаговане питання, тепер має бути зрозумілішим.
дредбанд

Відповіді:


83

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пітону dict, і json.loadsочікуєте дійсного, json stringякий повинен мати <type 'str'>.

Отже, якщо ви намагаєтеся завантажити json, вам слід змінити те, що ви завантажуєте, щоб виглядати як json_stringвище, або ви повинні його скинути. Це лише моє найкраще здогадування з поданої інформації. Що ви намагаєтесь досягти?

Також вам не потрібно вказувати uпопередні ваші рядки, як @Cld згадувалося в коментарях.


2
json.loads завантажить -> json-об'єкт <- у python dict - Це суперечить тому, що сказано в документах, і навіть тому, що робить ваш власний код - ви використовуєте load () для рядка, а не json об’єкт .
7stud

Так @ 7stud, ви маєте рацію, він завантажує рядок. Але він повинен бути дійсним рядком json. Я оновив свою відповідь.
Yep_It's_Me

186

У мене виникла ще одна проблема, яка повертає ту саму помилку.

Випуск єдиної цитати

Я використовував рядок 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 dictionnary (тому ви повинні слідувати синтаксису словника словника 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 документація

ast Python 3 doc

ast Python 2 doc

Інструмент

Якщо ви часто редагуєте 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 Pande

json.loads (strs.replace ('u "', '')) не працює. Ось наведена нижче помилка, Traceback (останній виклик останній): Файл" <stdin> ", рядок 1, у <module> Файл "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/__init__.py", рядок 338, при завантаженні return _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/reitions ) Тепер ви можете хотіти дати +1 :)
Rishabh Agrahari

1
о, ти маєш рацію! Додано до січня 2018 р. Вибачається та +1 :)
fedorqui 'ТАК перестати шкодити'

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

0

Інший випадок, коли я стикався з цим, коли я використовував echoконвеєр JSON у свій сценарій python і необережно загортав рядок JSON у подвійні лапки:

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

Зверніть увагу, що сам рядок JSON містить лапки, і я повинен був зробити:

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

Як це було, це те , що отримав сценарій пітона: {thumbnailWidth: 640}; подвійні лапки фактично були позбавлені.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.