Python neden bu JSON verilerini ayrıştıramıyor?


1439

Bir dosyada bu JSON var:

{
    "maps": [
        {
            "id": "blabla",
            "iscategorical": "0"
        },
        {
            "id": "blabla",
            "iscategorical": "0"
        }
    ],
    "masks": [
        "id": "valore"
    ],
    "om_points": "value",
    "parameters": [
        "id": "valore"
    ]
}

Tüm JSON verilerini yazdırmak için bu komut dosyasını yazdım:

import json
from pprint import pprint

with open('data.json') as f:
    data = json.load(f)

pprint(data)

Bu program bir istisna oluşturur, ancak:

Traceback (most recent call last):
  File "<pyshell#1>", line 5, in <module>
    data = json.load(f)
  File "/usr/lib/python3.5/json/__init__.py", line 319, in loads
    return _default_decoder.decode(s)
  File "/usr/lib/python3.5/json/decoder.py", line 339, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "/usr/lib/python3.5/json/decoder.py", line 355, in raw_decode
    obj, end = self.scan_once(s, idx)
json.decoder.JSONDecodeError: Expecting ',' delimiter: line 13 column 13 (char 213)

JSON'u nasıl ayrıştırabilir ve değerlerini nasıl çıkarabilirim?


@kederrac Verilen nedenden dolayı: "Bu soru bir yazım hatası veya artık yeniden üretilemeyen bir sorundan kaynaklandı." Json geçersiz.
Rob

@kederrac Sorun, yeniden üretilebildiği için değil kullanımdaki bir hatadan kaynaklanmaktadır.
Rob

Yanıtlar:


2128

Verileriniz geçerli JSON biçimi değil . Ne []zaman sahip olmanız gerekir {}:

  • []listPython'da çağrılan JSON dizileri içindir
  • {}dictPython'da çağrılan JSON nesneleri içindir

JSON dosyanızın şöyle görünmesi gerekir:

{
    "maps": [
        {
            "id": "blabla",
            "iscategorical": "0"
        },
        {
            "id": "blabla",
            "iscategorical": "0"
        }
    ],
    "masks": {
        "id": "valore"
    },
    "om_points": "value",
    "parameters": {
        "id": "valore"
    }
}

Ardından kodunuzu kullanabilirsiniz:

import json
from pprint import pprint

with open('data.json') as f:
    data = json.load(f)

pprint(data)

Verilerle artık aşağıdaki gibi değerleri de bulabilirsiniz:

data["maps"][0]["id"]
data["masks"]["id"]
data["om_points"]

Bunları deneyin ve bunun mantıklı olup olmayacağına bakın.


1
Bu yüzden json dosyası bir java nesnesinden üretildiğinden kodumu kontrol etmek zorundayım. Teşekkürler.
michele

5
Çözüm için teşekkürler. yazdırırken bir unicode sembolü alıyorum. (örneğin u'valore '). Nasıl önlenir?
diaryfolio

6
Güzel ama python u'her anahtardan önce bir ekler . Neden olduğu hakkında bir fikrin var mı?
CodyBugstein

7
Bu nedenle metniniz string değil unicode yazın. Çoğu zaman Alman umlaut'ları ve diğer sonuçları / programları vb. İle metin sonuçlarını paylaşmak için unicode metin olması daha iyidir. Demek iyisin!
Michael P

2
Umarım faydalı ve kesinlikle ironik bir gözlem yapmak isterim. Ben güzel baskı json için pprint modülünü json modülüne göre daha düşük buluyorum. İkisini de denerseniz, hemfikirsiniz. Benim json veri yapılarımı görüntülemek ve hata ayıklamak için yapıyorum: output = json.dumps (data_sttruc, indent = 2, sort_keys = True) print (output) Girinti denetimi, sıralama ve akıllı bulacağınızı düşünüyorum dumps () yönteminde satır kaydırmayı beğeninize göre ayarlayın. Düşüncem yanlışsa, lütfen biri bana bildirin.
Larold

307

Şöyle data.jsongörünmelisin:

{
 "maps":[
         {"id":"blabla","iscategorical":"0"},
         {"id":"blabla","iscategorical":"0"}
        ],
"masks":
         {"id":"valore"},
"om_points":"value",
"parameters":
         {"id":"valore"}
}

Kodunuz:

import json
from pprint import pprint

with open('data.json') as data_file:    
    data = json.load(data_file)
pprint(data)

with-Statement'e bağlı olduğu için bunun yalnızca Python 2.6 ve üstü sürümlerde çalıştığını unutmayın . Python 2.5 kullanımında from __future__ import with_statement, Python <2.4'te, bu cevabın dayandığı Justin Peel'in cevabına bakınız .

Artık şöyle tek değerlere de erişebilirsiniz:

data["maps"][0]["id"]  # will return 'blabla'
data["masks"]["id"]    # will return 'valore'
data["om_points"]      # will return 'value'

7
Bu konuda bir fikrim yok. Belki neden belli değildi, neden başka bir cevabın gerekli olduğunu düşündüm. With-ifadesinin uyumluluğu hakkında not eklendi.
Bengt

Geri alma işlemi için özür dileriz, ancak önerilen kod data_file opengerekenden daha uzun süre korunur.
Bengt

2.6 belgelerine ( docs.python.org/2.6/library/io.html ) başvurarak , "ile" bağlamında bir dosya açmak dosyayı otomatik olarak kapatır.
Steve S.

1
@SteveS. Evet, ancak içerik bırakılmadan önce değil. pprinting withşartına tutar data_filedaha uzun süre açık.
Bengt

1
Eğer böyle erişmek @GayanPathirage data["om_points"], data["masks"]["id"]. Fikir, 'anahtar yolları' belirterek sözlükteki herhangi bir seviyeye ulaşabilmenizdir. Bir KeyErroristisna alırsanız , anahtar yolda yok demektir. Yazım hatası olup olmadığına bakın veya sözlüğünüzün yapısını kontrol edin.
Nuhman

71

Justin Peel'in cevabı gerçekten yardımcı oluyor, ancak Python 3'ü kullanıyorsanız JSON'u şu şekilde yapmalısınız:

with open('data.json', encoding='utf-8') as data_file:
    data = json.loads(data_file.read())

Not: json.loadsyerine kullanın json.load. Python 3'te json.loadsbir dize parametresi alır. json.loaddosya benzeri bir nesne parametresini alır. data_file.read()bir dize nesnesi döndürür.

Dürüst olmak gerekirse, çoğu durumda tüm json verilerini belleğe yüklemek bir sorun olduğunu sanmıyorum.


10
Python 3'te neden json.loadbundan kaçınılmalıdır .loads?
Zearin

10
Bağladığınız sayfa kaçınmakla ilgili bir şey söylemiyor load.
Dan Hulme

28
Bu yanıt, Python 3 JSON dosyalarında tembel bir şekilde okunamayacağını ve bu yanlış olduğu zaman tüm dosyayı belleğe okur. Özür dilerim, ama net bir düşüş.
asukasz Rogalski

10
Bu cevap doğru değil. Json.load dosyasını python3'te açık bir dosya işleyici ile kullanmamanın bir nedeni yoktur. Downvote için özür dilerim, ancak yukarıdaki yorumları çok dikkatli okuduğunuz gibi görünmüyor.
dusktreader

5
+1 Bu cevap harika! Bunun için teşekkür ederim ve ben sadece dosya olmayan dizeleri ve ağ isteği ile çalışmak neden çünkü dizeleri kullanabileceğiniz bir işlevi aramak için beni uzak çekti!
newpeople

54
data = []
with codecs.open('d:\output.txt','rU','utf-8') as f:
    for line in f:
       data.append(json.loads(line))

8
bir dosyada birden fazla json nesneniz varsa bu doğru çözümdür. json.loadsbirden fazla json nesnesinin kodunu çözmez. Aksi takdirde, 'Ekstra Veri' hatası alırsınız.
yasin_alm

Bu en iyi cevap. Aksi takdirde, 'Ekstra Veri' hatası verir.
Earthx9

39
Bir dosyada birden fazla json nesnesine sahip olmak, dosyanın kendisinin aslında geçerli json olmadığı anlamına gelir. Bir json dosyasına dahil edilecek birden çok nesneniz varsa, bunlar dosyanın en üst düzeyindeki bir dizide bulunmalıdır.
dusktreader

Bir dosyada birden fazla json nesnesi bulunması, dosyanın tek bir json nesnesi olmadığı anlamına gelir. Bu çok açık. Nesnelerden tek bir dizi oluşturmak bariz bir çözümdür. Ama JSON hemen her düzeyde (tarafından açıkça sonlandırıldı tasarım gereğidir }, ]ya "). Bu nedenle, belirsizliği olmadan, tek bir dizede veya tek bir dosyada birden çok nesneyi birleştirebilirsiniz. Buradaki sorun, tek bir nesneyi bekleyen bir ayrıştırıcının, birden fazla nesne iletildiğinde başarısız olmasıdır.
MSalters

Tek bir dosya içinde birden fazla JSON nesneleri depolamak Reklam: - var olduğu için bir "standart" jsonlines.org/examples içinde .jsonl(json hatları), objeler önemsiz ayrıştırma için ön işlem yapan bir satır karakteri ile ayrılır ve sağlar başlangıç ​​/ bitiş işaretleri hakkında endişelenmeden dosyaları kolayca bölmek / toplu olarak kullanmak için.
Sebi

13

"Ultra JSON" veya basitçe "ujson", []JSON dosya girişinizde bulunan işlemleri yapabilir. Bir JSON giriş dosyasını programınıza JSON öğelerinin bir listesi olarak okuyorsanız; gibi [{[{}]}, {}, [], etc...]ujson listelerin sözlük, sözlük listelerinin isteğe göre bir işleyebilir.

Ujson'u Python paket dizininde bulabilirsiniz ve API Python'un yerleşik jsonkütüphanesiyle neredeyse aynıdır .

ujson, daha büyük JSON dosyaları yüklüyorsanız da çok daha hızlıdır. Performans ayrıntılarını, sağlanan aynı bağlantıda diğer Python JSON kütüphanelerine kıyasla görebilirsiniz.


9

Python3 kullanıyorsanız ( connection.jsondosya) JSON'unuzu şu şekilde değiştirmeyi deneyebilirsiniz :

{
  "connection1": {
    "DSN": "con1",
    "UID": "abc",
    "PWD": "1234",
    "connection_string_python":"test1"
  }
  ,
  "connection2": {
    "DSN": "con2",
    "UID": "def",
    "PWD": "1234"
  }
}

Sonra aşağıdaki kodu kullanarak:

connection_file = open('connection.json', 'r')
conn_string = json.load(connection_file)
conn_string['connection1']['connection_string_python'])
connection_file.close()
>>> test1

1
bu aynı zamanda
2.7.5'te

17
bu, dosya tanıtıcısını açık bırakır. bir withifade kullanmak daha iyi olurdu
Corey Goldberg

6

İşte değiştirilmiş data.jsondosya ile:

{
    "maps": [
        {
            "id": "blabla",
            "iscategorical": "0"
        },
        {
            "id": "blabla",
            "iscategorical": "0"
        }
    ],
    "masks": [{
        "id": "valore"
    }],
    "om_points": "value",
    "parameters": [{
        "id": "valore"
    }]
}

Aşağıdaki satırları kullanarak konsoldaki verileri arayabilir veya yazdırabilirsiniz:

import json
from pprint import pprint
with open('data.json') as data_file:
    data_item = json.load(data_file)
pprint(data_item)

İçin beklenen çıktı print(data_item['parameters'][0]['id']):

{'maps': [{'id': 'blabla', 'iscategorical': '0'},
          {'id': 'blabla', 'iscategorical': '0'}],
 'masks': [{'id': 'valore'}],
 'om_points': 'value',
 'parameters': [{'id': 'valore'}]}

İçin beklenen çıktı print(data_item['parameters'][0]['id']):

valore

"Haritaların" kaç gözleminin olduğunu saymak için bir sütun eklemek istersek, bu işlevi nasıl yazabiliriz?
Chenxi

5

Bu ayrıştırmada iki tür vardır.

  1. Sistem yolundan bir dosyadan veri ayrıştırma
  2. Uzak URL'den JSON ayrıştırma.

Bir dosyadan aşağıdakileri kullanabilirsiniz

import json
json = json.loads(open('/path/to/file.json').read())
value = json['key']
print json['value']

Bu arktikül, iki senaryo kullanarak değerleri tam olarak ayrıştırmayı ve almayı açıklar. Python kullanarak JSON ayrıştırma


4

Bir python3 kullanıcısı olarak ,

loadVe loadsyöntemleri arasındaki fark , özellikle json verilerini dosyadan okuduğunuzda önemlidir.

Dokümanlarda belirtildiği gibi:

json.load:

Bu dönüşüm tablosunu kullanarak fp (a .read () - bir JSON belgesi içeren metin dosyasını veya ikili dosyayı destekleyen) Python nesnesine serileştirin.

json.loads:

json.loads: Bu dönüşüm tablosunu kullanarak bir Python nesnesine s (bir JSON belgesi içeren str, bayt veya bytearray örneği) serisini kaldırın.

json.load yöntemi, ikili dosyayı okuyabildiğinden doğrudan açılan json belgesini doğrudan okuyabilir.

with open('./recipes.json') as data:
  all_recipes = json.load(data)

Sonuç olarak, json verileriniz bu dönüşüm tablosuna göre belirtilen biçimde kullanılabilir:

https://docs.python.org/3.7/library/json.html#json-to-py-table


Bu sorulan soruya nasıl bir cevap? Kullanıcı json dosyasını yüklemek için doğru yöntemi kullanıyordu.
Raj006
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.