Python json.loads değeri ValueError: Ekstra veri gösterir


151

JSON dosya "new.json" bazı veri alıyorum ve bazı verileri filtre ve yeni bir JSON dosyasına depolamak istiyorum. İşte benim kod:

import json
with open('new.json') as infile:
    data = json.load(infile)
for item in data:
    iden = item.get["id"]
    a = item.get["a"]
    b = item.get["b"]
    c = item.get["c"]
    if c == 'XYZ' or  "XYZ" in data["text"]:
        filename = 'abc.json'
    try:
        outfile = open(filename,'ab')
    except:
        outfile = open(filename,'wb')
    obj_json={}
    obj_json["ID"] = iden
    obj_json["VAL_A"] = a
    obj_json["VAL_B"] = b

ve bir hata alıyorum, geri izleme:

  File "rtfav.py", line 3, in <module>
    data = json.load(infile)
  File "/usr/lib64/python2.7/json/__init__.py", line 278, in load
    **kw)
  File "/usr/lib64/python2.7/json/__init__.py", line 326, in loads
    return _default_decoder.decode(s)
  File "/usr/lib64/python2.7/json/decoder.py", line 369, in decode
    raise ValueError(errmsg("Extra data", s, end, len(s)))
ValueError: Extra data: line 88 column 2 - line 50607 column 2 (char 3077 - 1868399)

Birisi bana yardım edebilir mi?

İşte new.json'daki verilerin bir örneği, dosyada yaklaşık 1500 daha fazla sözlük var

{
    "contributors": null, 
    "truncated": false, 
    "text": "@HomeShop18 #DreamJob to professional rafter", 
    "in_reply_to_status_id": null, 
    "id": 421584490452893696, 
    "favorite_count": 0, 
    "source": "<a href=\"https://mobile.twitter.com\" rel=\"nofollow\">Mobile Web (M2)</a>", 
    "retweeted": false, 
    "coordinates": null, 
    "entities": {
        "symbols": [], 
        "user_mentions": [
            {
                "id": 183093247, 
                "indices": [
                    0, 
                    11
                ], 
                "id_str": "183093247", 
                "screen_name": "HomeShop18", 
                "name": "HomeShop18"
            }
        ], 
        "hashtags": [
            {
                "indices": [
                    12, 
                    21
                ], 
                "text": "DreamJob"
            }
        ], 
        "urls": []
    }, 
    "in_reply_to_screen_name": "HomeShop18", 
    "id_str": "421584490452893696", 
    "retweet_count": 0, 
    "in_reply_to_user_id": 183093247, 
    "favorited": false, 
    "user": {
        "follow_request_sent": null, 
        "profile_use_background_image": true, 
        "default_profile_image": false, 
        "id": 2254546045, 
        "verified": false, 
        "profile_image_url_https": "https://pbs.twimg.com/profile_images/413952088880594944/rcdr59OY_normal.jpeg", 
        "profile_sidebar_fill_color": "171106", 
        "profile_text_color": "8A7302", 
        "followers_count": 87, 
        "profile_sidebar_border_color": "BCB302", 
        "id_str": "2254546045", 
        "profile_background_color": "0F0A02", 
        "listed_count": 1, 
        "profile_background_image_url_https": "https://abs.twimg.com/images/themes/theme1/bg.png", 
        "utc_offset": null, 
        "statuses_count": 9793, 
        "description": "Rafter. Rafting is what I do. Me aur mera Tablet.  Technocrat of Future", 
        "friends_count": 231, 
        "location": "", 
        "profile_link_color": "473623", 
        "profile_image_url": "http://pbs.twimg.com/profile_images/413952088880594944/rcdr59OY_normal.jpeg", 
        "following": null, 
        "geo_enabled": false, 
        "profile_banner_url": "https://pbs.twimg.com/profile_banners/2254546045/1388065343", 
        "profile_background_image_url": "http://abs.twimg.com/images/themes/theme1/bg.png", 
        "name": "Jayy", 
        "lang": "en", 
        "profile_background_tile": false, 
        "favourites_count": 41, 
        "screen_name": "JzayyPsingh", 
        "notifications": null, 
        "url": null, 
        "created_at": "Fri Dec 20 05:46:00 +0000 2013", 
        "contributors_enabled": false, 
        "time_zone": null, 
        "protected": false, 
        "default_profile": false, 
        "is_translator": false
    }, 
    "geo": null, 
    "in_reply_to_user_id_str": "183093247", 
    "lang": "en", 
    "created_at": "Fri Jan 10 10:09:09 +0000 2014", 
    "filter_level": "medium", 
    "in_reply_to_status_id_str": null, 
    "place": null
} 

Bu, JSON girişinde satır başına birden fazla nesne olduğunda aldığınız hatadır. Buradaki cevabın çoğu, her satırda sadece bir nesne olduğunu varsayar veya buna uyan örnekler oluşturur, ancak durum böyle değilse kırılacaktır.
smci

@smci: Hattı açıklayabilir misinmore than one object per line
aspiring1

Yanıtlar:


150

Aşağıdaki örnekte görebileceğiniz gibi, json.loads(ve json.load) birden çok json nesnesinin kodunu çözmez.

>>> json.loads('{}')
{}
>>> json.loads('{}{}') # == json.loads(json.dumps({}) + json.dumps({}))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Python27\lib\json\__init__.py", line 338, in loads
    return _default_decoder.decode(s)
  File "C:\Python27\lib\json\decoder.py", line 368, in decode
    raise ValueError(errmsg("Extra data", s, end, len(s)))
ValueError: Extra data: line 1 column 3 - line 1 column 5 (char 2 - 4)

Birden fazla sözlük dökümü yapmak istiyorsanız, bunları bir listeye sarın, listeyi boşaltın (sözlükleri birden çok kez boşaltmak yerine)

>>> dict1 = {}
>>> dict2 = {}
>>> json.dumps([dict1, dict2])
'[{}, {}]'
>>> json.loads(json.dumps([dict1, dict2]))
[{}, {}]

7
Yukarıda verdiğim koda referans olarak tekrar açıklayabilir misiniz? Ben bir acemiyim ve bazen bu tür şeyleri kavramak uzun zaman alıyor.
Apoorv Ashutosh

1
@ApoorvAshutosh, Görünüşe göre new.jsonbir json ve başka bir fazlalık veri içeriyor. json.load, json.loadssadece bir json kodunu çözebilir. ValueErrorGördüğünüz gibi ek verilerle karşılaştığında bir zam oluşturur .
falsetru

New.json'dan bir örnek yapıştırdım ve ondan bazı verileri filtreliyorum, bu yüzden fazladan veri aldığım yere ulaşmıyorum
Apoorv Ashutosh

1
@ ApoorvAshutosh, Düzenlenmiş soruda bu tür 1500 sözlük daha söylediniz . Bu ek veriler. Yapan sizseniz new.json, bir dosyaya tek bir json koyun.
falsetru

1
@ApoorvAshutosh, Birden fazla sözlükleri json olarak dökmeniz gerekiyorsa, bunları bir listeye sarın ve listeyi dökün.
falsetru

101

jsonifyingHer satırda bir dosyadan okuyabilirsiniz :

tweets = []
for line in open('tweets.json', 'r'):
    tweets.append(json.loads(line))

Bu, ara python nesnelerinin depolanmasını önler. append()Arama başına tam bir tweet yazdığınız sürece , bu işe yaramalıdır .


7
Kabul edilen cevap, dışa aktarma işlemini kontrol ederseniz sorunun kaynağını nasıl düzeltebileceğinizi ele alır, ancak başka birinin verilerini kullanıyorsanız ve bununla uğraşmanız gerekiyorsa, bu harika bir düşük maliyetli yöntemdir.
charlesreid1

3
Günümüzde birçok veri seti (örneğin: Yelp veri seti) Json nesnelerinin "seti" olarak sunulmaktadır ve yaklaşımınız bunları yüklemek için uygundur.
Gabrer

36

MongoDB'den atılan bir JSON dosyasını yüklemeye çalıştığım için bununla karşılaştım. Bana bir hata veriyordu

JSONDecodeError: Extra data: line 2 column 1

MongoDB JSON dökümü satır başına bir nesneye sahiptir, bu yüzden benim için işe yarayan şey:

import json
data = [json.loads(line) for line in open('data.json', 'r')]

13

Bu durum, JSON dosyanız yalnızca 1 JSON kaydı değilse de olabilir. Bir JSON kaydı şöyle görünür:

[{"some data": value, "next key": "another value"}]

Bir parantez [] ile açılır ve kapanır, parantez içinde parantezler {} vardır. Birçok çift diş teli olabilir, ancak hepsi yakın bir braketle biter]. Json dosyanız bunlardan birden fazlasını içeriyorsa:

[{"some data": value, "next key": "another value"}]
[{"2nd record data": value, "2nd record key": "another value"}]

yükler () başarısız olur.

Bunu başarısız olan kendi dosyam ile doğruladım.

import json

guestFile = open("1_guests.json",'r')
guestData = guestFile.read()
guestFile.close()
gdfJson = json.loads(guestData)

Bu çalışır çünkü 1_guests.json bir kayıt [] vardır. All_guests.json kullanmakta olduğum orijinal dosya, satırsonu ile ayrılmış 6 kayıt vardı. 5 kaydı sildim (daha önce köşeli parantezle işaretlenmesini kontrol ettim) ve dosyayı yeni bir adla kaydettim. Sonra ifadeleri çalıştı.

Hata (önceki değeri)

   raise ValueError(errmsg("Extra data", s, end, len(s)))
ValueError: Extra data: line 2 column 1 - line 10 column 1 (char 261900 - 6964758)

PS. Kelime kaydını kullanıyorum, ama bu resmi isim değil. Ayrıca, dosyanızda benim gibi yeni satır karakterleri varsa, bir kerede bir json değişkenine bir kayıt yüklemek () için döngü yapabilirsiniz.


2
Yeni json.loadssatırla sınırlandırılmış json parçalarını okumanın bir yolu var mı ? Yani, nasıl davranacak [json.loads(x) for x in text.split('\n')]? İlgili: json.dumpsÇıktısına varsayılan girintilemeyle birlikte gerçek satırlar içermeyecek bir garanti var mı ?
Ben

1
@Ben, varsayılan json.dumpsolarak metin içeriğinizdeki yeni satırları json'unuzu "\n"tek bir satıra tutarak değiştirir .
jchook

7

Birisine yardım edebilir. json dosyam böyle iken ben sadece aynı hatayı aldım

{"id":"1101010","city_id":"1101","name":"TEUPAH SELATAN"}
{"id":"1101020","city_id":"1101","name":"SIMEULUE TIMUR"}

ve ben hatalı biçimlendirilmiş buldum, bu yüzden onu

{
  "datas":[
    {"id":"1101010","city_id":"1101","name":"TEUPAH SELATAN"},
    {"id":"1101020","city_id":"1101","name":"SIMEULUE TIMUR"}
  ]
}

1
tıpkı seninki gibi yükleniyor, json.load (infile)
Akbar Noto

6

Sorununuz için tek astar:

data = [json.loads(line) for line in open('tweets.json', 'r')]

1
Bu genel bir çözüm değildir, girdinin satır başına bir JSON nesnesi olduğunu varsayar ve keser.
smci

3

İki astarlı bir şekilde çözmek istiyorsanız, bunu şu şekilde yapabilirsiniz:

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

1

Bence bir listeye dikte kaydetmek, @falsetru tarafından önerilen ideal bir çözüm değildir.

Daha iyi bir yol, diktelerin tekrarlanması ve yeni bir satır ekleyerek .json'a kaydedilmesidir.

2 sözlükümüz

d1 = {'a':1}

d2 = {'b':2}

onları .json'a yazabilirsiniz

import json
with open('sample.json','a') as sample:
    for dict in [d1,d2]:
        sample.write('{}\n'.format(json.dumps(dict)))

ve herhangi bir sorun olmadan json dosyasını okuyabilirsiniz

with open('sample.json','r') as sample:
    for line in sample:
        line = json.loads(line.strip())

basit ve verimli


Bu genel bir çözüm değildir, girdinin satır başına bir JSON nesnesi olduğunu varsayar ve keser.
smci
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.