Python / Json: oczekiwana nazwa właściwości ujęta w podwójne cudzysłowy


120

Próbowałem znaleźć dobry sposób ładowania obiektów JSON w Pythonie. Wysyłam te dane json:

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

do zaplecza, gdzie zostanie odebrany jako ciąg, a następnie json.loads(data)go przeanalizowałem.

Ale za każdym razem dostałem ten sam wyjątek:

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

Wyszukałem w Google, ale wydaje się, że nic nie działa poza tym rozwiązaniem, json.loads(json.dumps(data))które osobiście wydaje mi się nie tak wydajne, ponieważ akceptuje wszelkiego rodzaju dane, nawet te, które nie są w formacie json.

Wszelkie sugestie będą mile widziane.


20
Mój błąd nie polegał na podwójnym cytowaniu. Dodawałem przecinek po ostatniej parze klucz-wartość, tak jak robimy to w Pythonie. Nie robisz tego w JSON.
— Luv33preet

4
zawsze używaj, json.dumps()a nie tylko pisząc Pythona i mając nadzieję, że notacja Pythona będzie działać w twoim czytniku JavaScript.
— vy32

Miałem ten problem, ponieważ wziąłem wynik a print(jsonpickle_deserialized_object_string)i próbowałem go użyć. Z jakiegoś powodu print()zmienia notowania z "na'
— StingyJack

@ Luv33preet, dzięki, udało mi się to rozwiązać. ale spodziewam się logger-msg jako brakującego przecinka czy czegoś takiego, ale ten błąd nic o tym nie mówi,
— ganeshdeshmukh

Odpowiedzi:


161

To:

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

nie jest JSON.
To:

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

to JSON.

EDYCJA:
Niektórzy komentatorzy sugerowali, że powyższe nie wystarczy.
Specyfikacja JSON - RFC7159 stwierdza, że ​​ciąg znaków zaczyna się i kończy cudzysłowem. To jest ".
Pojedynczy quoute 'nie ma znaczenia semantycznego w JSON i jest dozwolony tylko wewnątrz ciągu.


4
Dzięki :) Nie zwróciłem na to uwagi, używam poprawnego formatu json podczas wysyłania danych, ale gdy są one odbierane na zapleczu, podwójne cudzysłowy są zastępowane pojedynczymi! dlatego mam ten wyjątek.
— raeX

35
to nie jest rozwiązanie. Rozwiązanie podpowiedziałoby mu, jak zmodyfikować łańcuch do prawidłowego formatu json.
— FistOfFury

2
@FistOfFury Przykro mi, ale twoje oświadczenie opiera się na fałszywym założeniu, że dowolny nieprawidłowy ciąg JSON można niezawodnie przekształcić programowo w prawidłowy. Wiele odpowiedzi na to pytanie próbuje rozwiązać problem, zastępując „na” itd. Czy muszę podać proste przykłady ciągów wejściowych, które zepsują te „rozwiązania”? Najwyraźniej OP zrozumiał, że to, z czym mamy do czynienia, nie jest JSON i mogłem kontynuować - zaakceptowałem moją odpowiedź. Wskazówka - ciąg wejściowy wygląda bardziej jak wynik metody Python dict .__ repr __ ().
— ElmoVanKielmo

4
@ElmoVanKielmo nie zmienia faktu, że Twoja odpowiedź jest stwierdzeniem, a nie odpowiedzią na pytanie. Nie podajesz kontekstu ani wyjaśnienia. Osoby, które przyjdą tutaj w poszukiwaniu informacji na temat pytania, będą rozczarowane. Być może pomogłeś OP, ale innym nie tak bardzo.
— FistOfFury

Zwykłe, jasne stwierdzenie często bardzo pomaga. Zwłaszcza, gdy w pobliżu jest mnóstwo innych odpowiedzi.
— Ben

55

Ponieważ JSON pozwala tylko na umieszczanie ciągów znaków w cudzysłowach, możesz manipulować łańcuchem w następujący sposób:

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

jeśli twój JSON zawiera pojedyncze cudzysłowy ( \'), to powinieneś użyć bardziej precyzyjnego następującego kodu:

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

Spowoduje to zastąpienie wszystkich wystąpień pojedynczego cudzysłowu podwójnym cudzysłowem w ciągu JSON, straw tym drugim przypadku nie spowoduje zastąpienia pojedynczych cudzysłowów ze zmianą znaczenia.

Możesz również użyć js-beautifymniej rygorystycznego:

$ pip install jsbeautifier
$ js-beautify file.js

4
Nie jest to dobry pomysł, ponieważ może zastąpić wszystkie „s, co jest złe”: PRZYKŁAD: „jest zły” -> „jest zły” -> źle
— sformułowany

@Reihan_amn Dodałem bardziej precyzyjną alternatywę wyrażenia regularnego dla przypadków, w których używane są pojedyncze cudzysłowy.
— elig

wyrażenie regularne podaje błąd składni
— Wolfgang Fahl

@WolfgangFahl, możesz teraz spróbować ponownie.
— elig


35

W moim przypadku podwójne cudzysłowy nie stanowiły problemu.

Ostatni przecinek dał mi ten sam komunikat o błędzie.

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

Aby usunąć ten przecinek, napisałem prosty kod.

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)

I to zadziałało dla mnie.


4
+1 Mogę to potwierdzić. Końcowy przecinek powoduje wyświetlenie tego komunikatu o błędzie. Przykład: echo '{"json":"obj",}' | python -m json.tool po uruchomieniu w powłoce zwraca „Oczekiwana nazwa właściwości ujęta w podwójne cudzysłowy: wiersz 1 kolumna 15 (znak 14)”. Końcowe przecinki nie są legalnym formatem JSON, ale byłoby miło, gdyby moduł Python JSON wyemitował w tym przypadku odpowiedni komunikat o błędzie.
— Laryx Decidua

8

Po prostu ten ciąg nie jest prawidłowym kodem JSON. Jak mówi błąd, dokumenty JSON muszą używać podwójnych cudzysłowów.

Musisz naprawić źródło danych.


7

Sprawdziłem Twoje dane JSON

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

w http://jsonlint.com/, a wyniki były następujące:

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

zmodyfikowanie go na następujący ciąg rozwiązuje błąd JSON:

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

2
DZIĘKUJEMY ZA TO LINK!
— WolVes

7

Ciągi JSON muszą zawierać podwójne cudzysłowy. Biblioteka JSON python wymusza to, więc nie możesz załadować swojego ciągu. Twoje dane muszą wyglądać następująco:

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

Jeśli to nie jest coś, co możesz zrobić, możesz użyć ast.literal_eval()zamiastjson.loads()


3
To nie jest ograniczenie biblioteki Pythona, ale samego formatu JSON.
— Daniel Roseman,

Masz rację. Jednak niektóre parsery JSON nie wymuszają podwójnych cudzysłowów. Zaktualizuję odpowiedź.
— alexbclay

pod warunkiem, że ten nie-JSON nigdy nie ma podwójnych cudzysłowów w ciągach z pojedynczym cudzysłowem, wszystko, co musisz zrobić, to zamienić wszystkie pojedyncze json.loads()
— znaki

2
Użycie ast.literal_evalspowoduje ValueError: malformed string, że ciąg JSON ma wartość logiczną.
— 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)

to rozwiąże problem.


3

Jak jasno mówi się błędnie, nazwy powinny być ujęte w podwójne cudzysłowy zamiast w apostrofy. Przekazany ciąg nie jest prawidłowym plikiem JSON. Tak powinno wyglądać

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

2

Użyłem tej metody i udało mi się uzyskać pożądany wynik. mój skrypt

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

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

wynik

>>> 0

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

U mnie to zadziałało doskonale. Dzięki.


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

Chociaż jest to poprawne rozwiązanie, ale może prowadzić do sporego bólu głowy, jeśli istnieje taki 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}}}}

Zauważyłeś tę „prawdziwą” wartość? Użyj tego, aby rzeczy były podwójnie sprawdzane pod kątem wartości logicznych. Obejmuje to te przypadki -

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

Upewnij się też, że nie robisz

x = json.loads(x)

To musi być inna zmienna.


1

Miałem podobny problem. Dwa komponenty komunikujące się ze sobą korzystały z kolejki.

Pierwszy komponent nie wykonywał json.dumps przed umieszczeniem wiadomości w kolejce. Więc ciąg JSON wygenerowany przez komponent odbierający był w apostrofach. To powodowało błąd

 Expecting property name enclosed in double quotes

Dodanie json.dumps rozpoczęło tworzenie poprawnie sformatowanego JSON i rozwiązano problem.


0

Użyj evalfunkcji.

Dba o rozbieżność między pojedynczymi i podwójnymi cudzysłowami.


NIGDY nie używaj eval na wejściu użytkownika ani danych przychodzących z żądaniem HTTP. To jest ogromny problem bezpieczeństwa.
— ElmoVanKielmo

0

Jak wyjaśniają inne odpowiedzi, błąd występuje z powodu nieprawidłowych znaków cudzysłowu przekazanych do modułu json.

W moim przypadku nadal uzyskać ValueError nawet po wymianie 'z "moim sznurkiem. W końcu zdałem sobie sprawę, że niektóre znaki Unicode podobne do cytatów znalazły się w moim ciągu:

 “  ”  ‛  ’  ‘  `  ´  ″  ′ 

Aby wyczyścić to wszystko, możesz po prostu przekazać ciąg przez wyrażenie regularne:

import re

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

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

json_object = json.loads(parsed_string)


-1

Wielokrotnie napotykałem ten problem, gdy JSON był edytowany ręcznie. Jeśli ktoś miałby coś usunąć z pliku nie zauważając, może wyrzucić ten sam błąd.

Na przykład, jeśli brakuje ostatniego „}” JSON, spowoduje to ten sam błąd.

Jeśli więc edytujesz plik ręcznie, upewnij się, że sformatowałeś go tak, jak oczekuje tego dekoder JSON, w przeciwnym razie napotkasz ten sam problem.

Mam nadzieję że to pomoże!


-2

Stosowanie tej json.dumps()metody jest zawsze idealne . Aby pozbyć się tego błędu, użyłem następującego kodu

json.dumps(YOUR_DICT_STRING).replace("'", '"')
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.