Python / Json: имя свойства должно быть заключено в двойные кавычки

121

Я пытался найти хороший способ загрузки объектов 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.

Мы будем очень благодарны за любые предложения.

raeX
источник
21
Моя ошибка заключалась не в двойных кавычках. Я добавлял запятую после последней пары ключ-значение, как мы это делаем в python. Вы не делаете этого в JSON.
Luv33preet 05
5
всегда используйте, json.dumps()а не просто записывайте python и надеясь, что нотация python будет работать в вашем читателе JavaScript.
vy32
У меня возникла эта проблема, потому что я взял результат a print(jsonpickle_deserialized_object_string)и попытался его использовать. Почему-то print()меняет цитаты с "на'
StingyJack
@ Luv33preet, спасибо, проблема решена. но я ожидаю, что logger-msg будет отсутствовать-запятая или что-то в этом роде, но эта ошибка ничего об этом не говорит,
ganeshdeshmukh
см. stackoverflow.com/a/63862387/1497139 для быстрого исправления
Вольфганг Фаль

Ответы:

162

Этот:

{'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 и разрешены только внутри строки.

ElmoVanKielmo
источник
4
Спасибо :) Я не обратил на это внимания, я использую правильный формат json при отправке данных, но когда он получен на бэкэнде, двойные кавычки заменяются одиночными! поэтому я получил это исключение.
raeX
39
это не решение. Решение подскажет, как преобразовать строку в действительный json.
FistOfFury
2
@FistOfFury Мне очень жаль, но ваше утверждение основано на ложном предположении, что произвольная недопустимая строка JSON может быть надежно преобразована программно в действительную. Многие ответы на этот вопрос пытаются решить проблему, заменив "на" и т. Д. Должен ли я дать вам простые примеры входных строк, которые нарушат эти "решения"? Очевидно OP понял, что то, с чем мы имеем дело, не JSON и смог продолжить - принял мой ответ. Подсказка - входная строка больше похожа на вывод метода Python dict .__ repr __ ().
ElmoVanKielmo
4
@ElmoVanKielmo не меняет того факта, что ваш ответ является утверждением, а не ответом на вопрос. Вы не предоставляете никакого контекста или объяснения. Люди, приходящие сюда в поисках информации по этому вопросу, будут разочарованы. Возможно, вы помогли OP, но другим не очень.
FistOfFury
Часто очень помогает простое ясное изложение. Особенно, когда вокруг много других ответов.
Бен
56

поскольку 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
спасибо, я сейчас использую stackoverflow.com/a/63862387/1497139 вместо этого
Вольфганг Фаль
Я добавил тестовый пример testSingleQuoteToDoubleQuoteStackoverflow в github.com/WolfgangFahl/pyLoDStorage/blob/master/tests/… согласно обсуждению в stackoverflow.com/a/63862387/1497139 он показывает разницу в результатах: {'города': [{' name ': "Врата Верхнего Ада"}, {' name ': "Н'зето"}] {"города": [{"name": "Врата Верхнего Ада"}, {"name": "Н'зето" }] {"cities": [{"name": "Врата Верхнего ада"}, {"name": "N" zeto "}]
Вольфганг Фаль
35

В моем случае двойные кавычки не были проблемой.

Последняя запятая дала мне такое же сообщение об ошибке.

{'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)

И это сработало для меня.

Greentec
источник
4
+1 Я могу это подтвердить. Это сообщение об ошибке появляется после запятой. Пример: echo '{"json":"obj",}' | python -m json.tool при запуске в оболочке выдает «Ожидаемое имя свойства, заключенное в двойные кавычки: строка 1, столбец 15 (символ 14)». Завершающие запятые не являются допустимым JSON, но было бы неплохо, если бы модуль Python JSON в этом случае выдавал соответствующее сообщение об ошибке.
Laryx Decidua
8

Проще говоря, эта строка не является допустимым JSON. Как говорится в ошибке, документы JSON должны использовать двойные кавычки.

Вам необходимо исправить источник данных.

Дэниел Розман
источник
7

Я проверил ваши данные 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
7

Строки JSON должны использовать двойные кавычки. Библиотека Python JSON обеспечивает это, поэтому вы не можете загрузить свою строку. Ваши данные должны выглядеть так:

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

Если это не то, что вы можете сделать, вы можете использовать ast.literal_eval()вместоjson.loads()

alexbclay
источник
3
Это ограничение не для библиотеки Python, а для самого формата JSON.
Дэниел Роузман
Ты прав. Однако некоторые парсеры JSON не используют двойные кавычки. Я обновлю свой ответ.
Alexbclay
при условии, что этот не-JSON никогда не имеет двойных кавычек внутри строк с одинарными кавычками, все, что вам нужно сделать, это заменить все одиночные числа на двойные перед json.loads()
вызовом
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)

это решит проблему.

Balaji K
источник
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)

Это отлично сработало для меня. Спасибо.

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

Заметили это "Истинное" значение? Используйте это для двойной проверки логических значений. Это покроет те случаи -

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("'", '"')
Майкл Элиму
источник