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.

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


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


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)

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


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()


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)

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


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

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

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.