Birden çok JSON nesnesiyle bir JSON dosyasını yükleme ve ayrıştırma


101

Python'da bir JSON dosyası yüklemeye ve ayrıştırmaya çalışıyorum . Ama dosyayı yüklemeye çalışırken takıldım:

import json
json_data = open('file')
data = json.load(json_data)

Getiri:

ValueError: Extra data: line 2 column 1 - line 225116 column 1 (char 232 - 160128774)

18.2'yejson baktım . - Python belgelerinde JSON kodlayıcı ve kod çözücü , ancak bu korkunç görünümlü belgeleri okumak oldukça cesaret kırıcı.

İlk birkaç satır (rastgele girişlerle anonimleştirilmiş):

{"votes": {"funny": 2, "useful": 5, "cool": 1}, "user_id": "harveydennis", "name": "Jasmine Graham", "url": "http://example.org/user_details?userid=harveydennis", "average_stars": 3.5, "review_count": 12, "type": "user"}
{"votes": {"funny": 1, "useful": 2, "cool": 4}, "user_id": "njohnson", "name": "Zachary Ballard", "url": "https://www.example.com/user_details?userid=njohnson", "average_stars": 3.5, "review_count": 12, "type": "user"}
{"votes": {"funny": 1, "useful": 0, "cool": 4}, "user_id": "david06", "name": "Jonathan George", "url": "https://example.com/user_details?userid=david06", "average_stars": 3.5, "review_count": 12, "type": "user"}
{"votes": {"funny": 6, "useful": 5, "cool": 0}, "user_id": "santiagoerika", "name": "Amanda Taylor", "url": "https://www.example.com/user_details?userid=santiagoerika", "average_stars": 3.5, "review_count": 12, "type": "user"}
{"votes": {"funny": 1, "useful": 8, "cool": 2}, "user_id": "rodriguezdennis", "name": "Jennifer Roach", "url": "http://www.example.com/user_details?userid=rodriguezdennis", "average_stars": 3.5, "review_count": 12, "type": "user"}

Yanıtlar:


224

Bir var JSON Hatları biçimi metin dosyası . Dosyanızı satır satır ayrıştırmanız gerekir:

import json

data = []
with open('file') as f:
    for line in f:
        data.append(json.loads(line))

Her satır geçerli JSON içerir, ancak bir bütün olarak, üst düzey bir liste veya nesne tanımı olmadığından geçerli bir JSON değeri değildir.

Dosya, satır başına JSON içerdiğinden, hepsini tek seferde ayrıştırmaya veya akışlı bir JSON ayrıştırıcısı bulmaya çalışmanın baş ağrılarından kurtulmuş olduğunuzu unutmayın. Artık bir sonrakine geçmeden önce her satırı ayrı ayrı işlemeyi seçerek bu işlem sırasında bellek tasarrufu yapabilirsiniz. Muhtemelen her sonucu tek bir listeye eklemek ve ardından dosyanız gerçekten büyükse her şeyi işlemek istemezsiniz .

Aralarında sınırlayıcılar olan ayrı JSON nesneleri içeren bir dosyanız varsa , bir seferde bir JSON nesnesinde okumak için 'json' modülünü nasıl kullanabilirim? tamponlu bir yöntem kullanarak tek tek nesneleri ayrıştırmak için.


2
+1 Belki de şunu belirtmekte fayda var ki, tüm nesnelere aynı anda ihtiyacınız yoksa, onları tek tek işlemenin daha verimli bir yaklaşım olabilir. Bu şekilde tüm verileri bellekte değil tek bir parçasını depolamanıza gerek kalmaz.
Tadeck

1
@Pi_: Bir sözlüğünüz olacak, bu nedenle alanlara anahtar olarak erişmeniz yeterli:data = json.loads(line); print data[u'votes']
Martijn Pieters

1
@Pi_: json.loads () sonucunu yazdırın veya incelemek için hata ayıklayıcıyı kullanın.
Martijn Pieters

1
@Pi_: hayır; JSON formatını python dikte gösterimi ile karıştırmayın. Artık dizeleri olan python sözlükleri görüyorsunuz.
Martijn Pieters

1
@ user2441441: Buradaki gönderideki bağlantılı cevaba bakın .
Martijn Pieters


4

Yani bir kötü biçimlendirilmiş. Satır başına bir JSON nesneniz var, ancak bunlar daha büyük bir veri yapısında (yani bir dizi) yer almıyor. Ya her satırın sonunda virgülle [başlayıp bitecek şekilde yeniden biçimlendirmeniz ya ]da ayrı sözlükler olarak satır satır ayrıştırmanız gerekir.


20
50MB'lık bir dosya ile OP muhtemelen veri ile satır satır uğraşmaktan daha iyidir. :-)
Martijn Pieters

11
Dosyanın kötü biçimlendirilmiş olup olmadığı kişinin bakış açısına bağlıdır. "JSON satırları" biçiminde olması amaçlanmışsa, geçerlidir. Bakınız: jsonlines.org
LS
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.