Python / Json: очікувана назва властивості, укладена у подвійні лапки


109

Я намагався знайти хороший спосіб завантажити об'єкти JSON у Python. Я надсилаю ці дані JSON:

{'http://example.org/about': {'http://purl.org/dc/terms/title': [{'type': 'literal', 'value': "Anna's Homepage"}]}}

до серверної частини, де вона буде отримана як рядок, тоді я json.loads(data)її синтаксично аналізував.

Але кожного разу я отримував той самий виняток:

ValueError: Expecting property name enclosed in double quotes: line 1 column 2 (char 1)

Я погуглив, але, здається, нічого не працює, крім цього рішення, json.loads(json.dumps(data))яке особисто мені здається не таким ефективним, оскільки воно приймає будь-які дані, навіть ті, що не мають формату json.

Будь-які пропозиції будуть дуже вдячні.


18
Моєю помилкою було не подвійне цитування. Я додавав кому після останньої пари ключ-значення, як це робимо в python. Ви не робите цього в JSON.
Luv33preet

4
завжди використовуйте, json.dumps()а не просто виписуйте python і сподіваючись, що позначення python буде працювати у вашому читачі JavaScript.
vy32

У мене була ця проблема, тому що я взяв результат a print(jsonpickle_deserialized_object_string)і спробував використати його. Чомусь print()змінює цитати з "на'
StingyJack

@ Luv33preet, дякую, це вирішено. але я очікую, що logger-msg відсутня кома або щось інше, але ця помилка нічого про це не говорить,
ganeshdeshmukh

див. stackoverflow.com/a/63862387/1497139 для швидкого виправлення
Wolfgang Fahl

Відповіді:


150

Це:

{'http://example.org/about': {'http://purl.org/dc/terms/title': [{'type': 'literal', 'value': "Anna's Homepage"}]}}

не є JSON.
Це:

{"http://example.org/about": {"http://purl.org/dc/terms/title": [{"type": "literal", "value": "Anna's Homepage"}]}}

є JSON.

РЕДАГУВАТИ:
Деякі коментатори вважали, що вищезазначеного недостатньо.
Специфікація JSON - RFC7159 говорить, що рядок починається і закінчується лапками. Тобто ".
Одинарна цитата 'не має семантичного значення в JSON і допускається лише всередині рядка.


4
Подяки :) Я не звертав на це уваги, я використовую правильний формат json під час надсилання даних, але коли вони надходять у серверну систему, подвійні лапки замінюються одинарними! тому я отримав цей виняток.
raeX

25
це не рішення. Рішення підкаже йому, як змінити рядок на дійсний json.
FistOfFury

2
@FistOfFury Вибачте, але ваше твердження базується на хибному припущенні, що довільний недійсний рядок JSON можна надійно програмно перетворити на дійсний. Багато відповідей на це запитання намагаються вирішити проблему, замінивши "на" тощо. Чи повинен я давати вам прості приклади вхідних рядків, які порушать ці "рішення"? Очевидно OP зрозумів, що те, з чим ми маємо справу, не є JSON і зміг продовжити - прийняв мою відповідь. Підказка - вхідний рядок більше схожий на вихідний метод методу Python dict .__ repr __ ().
ElmoVanKielmo

4
@ElmoVanKielmo не змінює той факт, що ваша відповідь - це твердження, а не відповідь на запитання. Ви не надаєте жодного контексту чи пояснень. Люди, які приїжджають сюди і шукають інформацію щодо цього питання, будуть розчаровані. Можливо, ви допомагали ОП, але іншим не так сильно.
FistOfFury

Просте чітке твердження часто дуже допомагає. Особливо, коли навколо багато інших відповідей.
Бен,

46

оскільки JSON дозволяє лише вкладати рядки у подвійні лапки, ви можете маніпулювати рядком таким чином:

str = str.replace("\'", "\"")

якщо у вашому JSON містяться одинарні лапки ( \'), вам слід скористатися більш точним наступним кодом:

import re
p = re.compile('(?<!\\\\)\'')
str = p.sub('\"', str)

Це замінить усі випадки одинарних лапок на подвійні лапки в рядку JSON, strа в останньому випадку не замінить екрановані одинарні лапки.

Ви також можете використовувати js-beautifyменш строгий:

$ pip install jsbeautifier
$ js-beautify file.js

4
Не гарна ідея, оскільки вона може замінити все на "s", що неправильно: ПРИКЛАД: "це погано" -> "це погано" -> неправильно сформований рядок
Reihan_amn

@Reihan_amn Я додав більш точну альтернативу регулярного виразу для випадків, коли використовуються екрановані одинарні лапки.
elig

регулярний вираз дає синтаксичну помилку
Вольфганг Фаль

@WolfgangFahl, ти можеш спробувати ще раз зараз.
elig

thx я використовую stackoverflow.com/a/63862387/1497139 замість цього зараз
Wolfgang Fahl

33

У моєму випадку подвійні лапки не були проблемою.

Остання кома дала мені таке саме повідомлення про помилку.

{'a':{'b':c,}}
           ^

Щоб видалити цю кому, я написав простий код.

import json

with open('a.json','r') as f:
    s = f.read()
    s = s.replace('\t','')
    s = s.replace('\n','')
    s = s.replace(',}','}')
    s = s.replace(',]',']')
    data = json.loads(s)

І це спрацювало для мене.


4
+1 Я можу це підтвердити. Кінцева кома видає це повідомлення про помилку. Приклад: echo '{"json":"obj",}' | python -m json.tool при запуску в оболонці видає "Очікуване ім'я властивості, укладене у подвійні лапки: рядок 1 стовпець 15 (char 14)". Команди завершення не є законними JSON, але було б непогано, якби модуль JSON Python видав відповідне повідомлення про помилку в цьому випадку.
Laryx Decidua

7

Просто, цей рядок не є дійсним JSON. Як свідчить помилка, у документах JSON потрібно використовувати подвійні лапки.

Вам потрібно виправити джерело даних.


6

Я перевірив ваші дані JSON

{'http://example.org/about': {'http://purl.org/dc/terms/title': [{'type': 'literal', 'value': "Anna's Homepage"}]}}

в http://jsonlint.com/ і результати:

Error: Parse error on line 1:
{   'http://example.org/
--^
Expecting 'STRING', '}', got 'undefined'

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

{
    "http://example.org/about": {
        "http://purl.org/dc/terms/title": [{
            "type": "literal",
            "value": "Anna's Homepage"
        }]
    }
}

2
ДЯКУЮ ЗА ЦЕ ПОСИЛАННЯ!
WolVes

6

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

{"http://example.org/about": {"http://purl.org/dc/terms/title": [{"type": "literal", "value": "Anna's Homepage"}]}}

Якщо це не те, що ви можете зробити, ви можете використовувати ast.literal_eval()замістьjson.loads()


3
Це не обмеження бібліотеки Python, а самого формату JSON.
Даніель Роузман

Ви праві. Однак деякі аналізатори JSON не застосовують подвійні лапки. Я оновлю свою відповідь.
alexbclay

за умови, що цей не-JSON ніколи не має жодних подвійних лапок всередині рядків з одинарними лапками, все, що вам потрібно зробити, це замінити всі сингли на подвійні перед викликомjson.loads()
nigel222

2
Використання ast.literal_evalпризведе до того, ValueError: malformed stringякщо рядок JSON має логічне значення.
Scratch'N'Purr

4
import ast

inpt = {'http://example.org/about': {'http://purl.org/dc/terms/title':
                                     [{'type': 'literal', 'value': "Anna's Homepage"}]}}

json_data = ast.literal_eval(json.dumps(inpt))

print(json_data)

це вирішить проблему.


3

Як чітко сказано в помилці, імена слід укладати в подвійні лапки замість одинарних лапок. Рядок, який ви передаєте, просто не є дійсним JSON. Це повинно виглядати так

{"http://example.org/about": {"http://purl.org/dc/terms/title": [{"type": "literal", "value": "Anna's Homepage"}]}}

2

Я використав цей метод і зумів отримати бажаний результат. мій сценарій

x = "{'inner-temperature': 31.73, 'outer-temperature': 28.38, 'keys-value': 0}"

x = x.replace("'", '"')
j = json.loads(x)
print(j['keys-value'])

вихід

>>> 0

2
with open('input.json','r') as f:
    s = f.read()
    s = s.replace('\'','\"')
    data = json.loads(s)

Це в мене спрацювало чудово. Дякую.


2
x = x.replace("'", '"')
j = json.loads(x)

Хоча це правильне рішення, але це може призвести до головного болю, якщо існує такий JSON -

{'status': 'success', 'data': {'equity': {'enabled': True, 'net': 66706.14510000008, 'available': {'adhoc_margin': 0, 'cash': 1277252.56, 'opening_balance': 1277252.56, 'live_balance': 66706.14510000008, 'collateral': 249823.93, 'intraday_payin': 15000}, 'utilised': {'debits': 1475370.3449, 'exposure': 607729.3129, 'm2m_realised': 0, 'm2m_unrealised': -9033, 'option_premium': 0, 'payout': 0, 'span': 858608.032, 'holding_sales': 0, 'turnover': 0, 'liquid_collateral': 0, 'stock_collateral': 249823.93}}, 'commodity': {'enabled': True, 'net': 0, 'available': {'adhoc_margin': 0, 'cash': 0, 'opening_balance': 0, 'live_balance': 0, 'collateral': 0, 'intraday_payin': 0}, 'utilised': {'debits': 0, 'exposure': 0, 'm2m_realised': 0, 'm2m_unrealised': 0, 'option_premium': 0, 'payout': 0, 'span': 0, 'holding_sales': 0, 'turnover': 0, 'liquid_collateral': 0, 'stock_collateral': 0}}}}

Помітили, що значення "True" ? Використовуйте це, щоб зробити подвійну перевірку на логічні значення. Це охопить ці випадки -

x = x.replace("'", '"').replace("True", '"True"').replace("False", '"False"').replace("null", '"null"')
j = json.loads(x)

Також переконайтеся, що ви цього не зробили

x = json.loads(x)

Це має бути інша змінна.


1

У мене була подібна проблема. Два компоненти, що взаємодіють між собою, використовували чергу.

Перший компонент не робив json.dumps перед тим, як поставити повідомлення в чергу. Отже, рядок JSON, що генерується компонентом, що отримує, містив одинарні лапки. Це спричинило помилку

 Expecting property name enclosed in double quotes

Додавши json.dumps, ми почали створювати правильно відформатований JSON і вирішили проблему.


0

Використовуйте evalфункцію.

Він піклується про розбіжності між одинарними та подвійними лапками.


НІКОЛИ не використовуйте eval при введенні користувачем, а також дані, що надходять із HTTP-запитом. Це величезна проблема безпеки.
ElmoVanKielmo

0

Оскільки інші відповіді добре пояснюють, помилка виникає через недійсні лапки, передані модулю json.

У моєму випадку я продовжував отримувати ValueError навіть після заміни 'на "в моєму рядку. Нарешті я зрозумів, що деякі символи юнікоду, подібні до цитат, знайшли свій шлях до мого рядка:

           `  ´     

Щоб очистити все це, ви можете просто передати рядок через регулярний вираз:

import re

raw_string = '{“key”:“value”}'

parsed_string = re.sub(r"[“|”|‛|’|‘|`|´|″|′|']", '"', my_string)

json_object = json.loads(parsed_string)

-1

Я неодноразово стикався з цією проблемою, коли JSON редагувався вручну. Якщо хтось мав видалити щось із файлу, не помічаючи, це може призвести до тієї ж помилки.

Наприклад, якщо ваш останній "}" останнього JSON відсутній, він видасть ту саму помилку.

Отже, якщо ви редагуєте файл вручну, переконайтеся, що ви відформатували його так, як це очікується декодером JSON, інакше ви зіткнетеся з тією ж проблемою.

Сподіваюся, це допомагає!


-2

Завжди ідеально використовувати json.dumps()метод. Щоб позбутися цієї помилки, я використав наступний код

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