Memuat dan mengurai file JSON dengan beberapa objek JSON


101

Saya mencoba memuat dan mengurai file JSON dengan Python . Tapi saya terjebak saat mencoba memuat file:

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

Hasil:

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

Saya melihat 18,2. json- Encoder dan decoder JSON dalam dokumentasi Python, tetapi cukup mengecewakan untuk membaca dokumentasi yang tampak mengerikan ini.

Beberapa baris pertama (dianonimkan dengan entri acak):

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

Jawaban:


222

Anda memiliki file teks format Garis JSON . Anda perlu mengurai file Anda baris demi baris:

import json

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

Setiap baris berisi JSON yang valid, tetapi secara keseluruhan, ini bukan nilai JSON yang valid karena tidak ada daftar level teratas atau definisi objek.

Perhatikan bahwa karena file tersebut berisi JSON per baris, Anda tidak perlu pusing lagi mencoba mengurai semuanya sekaligus atau mencari tahu pengurai JSON streaming. Sekarang Anda dapat memilih untuk memproses setiap baris secara terpisah sebelum melanjutkan ke baris berikutnya, menghemat memori dalam prosesnya. Anda mungkin tidak ingin menambahkan setiap hasil ke satu daftar dan kemudian memproses semuanya jika file Anda sangat besar.

Jika Anda memiliki file yang berisi objek JSON individual dengan pemisah di antaranya, gunakan Bagaimana cara menggunakan modul 'json' untuk membaca di satu objek JSON pada satu waktu? untuk mengurai objek individu menggunakan metode buffer.


2
+1 Mungkin perlu dicatat, bahwa jika Anda tidak membutuhkan semua objek sekaligus, memprosesnya satu per satu mungkin pendekatan yang lebih efisien. Dengan cara ini Anda tidak perlu menyimpan seluruh data di memori, tetapi hanya satu bagian saja.
Tadeck

1
@Pi_: Anda akan memiliki kamus, jadi cukup akses kolom sebagai kunci:data = json.loads(line); print data[u'votes']
Martijn Pieters

1
@Pi_: mencetak hasil dari json.loads () lalu atau gunakan debugger untuk memeriksa.
Martijn Pieters

1
@Pi_: tidak; jangan bingung antara format JSON dengan representasi python dict. Anda melihat kamus python dengan string sekarang.
Martijn Pieters

1
@ user2441441: lihat jawaban terkait dari posting di sini.
Martijn Pieters


4

Itu adalah sakit-diformat. Anda memiliki satu objek JSON per baris, tetapi objek tersebut tidak terdapat dalam struktur data yang lebih besar (yaitu, array). Anda juga perlu memformatnya sehingga dimulai dengan [dan diakhiri dengan ]koma di akhir setiap baris, atau parsing baris demi baris sebagai kamus terpisah.


20
Dengan file 50MB, OP mungkin lebih baik menangani data baris demi baris. :-)
Martijn Pieters

11
Format file tidak tepat tergantung pada sudut pandang seseorang. Jika dimaksudkan dalam format "garis JSON", itu valid. Lihat: jsonlines.org
LS
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.