Python json.loads显示ValueError:额外数据


151

我正在从JSON文件“ new.json”中获取一些数据,我想过滤一些数据并将其存储到新的JSON文件中。这是我的代码:

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

我收到一个错误,回溯是:

  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)

有人能帮我吗?

这是new.json中数据的示例,文件中还有约1500种这样的词典

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

每当输入JSON每行包含多个对象时,就会出现此错误。这里的许多答案都假设每行只有一个对象,或者构造了遵循该对象的示例,但是如果不是这样的话,它会中断。
smci

@smci:你能解释一下行more than one object per line
aspiring1

Answers:


150

如以下示例所示,json.loads(和json.load)不会解码多个json对象。

>>> 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)

如果要转储多个字典,请将它们包装在列表中,然后转储列表(而不是多次转储字典)

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

7
您能否参考我上面提供的代码再次进行解释?我是新手,有时需要很长时间才能掌握这些东西。
Apoorv Ashutosh 2014年

1
@ApoorvAshutosh,似乎new.json包含一个json和另一个冗余数据。json.loadjson.loads只能解码json。ValueError如您所见,它在遇到其他数据时会引发一个提示。
falsetru 2014年

从new.json中粘贴了一个示例,并且我正在从中过滤出一些数据,因此我无法从那里获得额外的数据
Apoorv Ashutosh 2014年

1
@ApoorvAshutosh,您在编辑过的问题中又说了1500种这样的词典。那是额外的数据。如果您是制作的人new.json,则只需在文件中放入一个json。
falsetru 2014年

1
@ApoorvAshutosh,如果您需要将多个词典转储为json,请将它们包装在列表中,然后转储该列表。
falsetru 2014年

100

您可以从文件中jsonifying逐行读取:

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

这样可以避免存储中间的python对象。只要您在每次append()通话中写一条完整的推文,它就可以工作。


7
如果您控制导出过程,则可接受的答案解决了如何解决问题的根源,但是,如果您使用别人的数据而只需要处理它,那么这是一种开销少的好方法。
charlesreid1年

3
如今,许多数据集(例如:Yelp数据集)都作为Json对象的“集合”提供,您的方法可以很方便地加载它们。
加布里尔'18

36

我碰到这个是因为我试图加载从MongoDB转储的JSON文件。这给我一个错误

JSONDecodeError: Extra data: line 2 column 1

MongoDB JSON转储每行有一个对象,因此对我有用的是:

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

13

如果您的JSON文件不只是1个JSON记录,也会发生这种情况。JSON记录如下所示:

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

它用方括号[]打开和关闭,方括号内是括号{}。可以有许多对括号,但它们的结尾都带有一个括号[]。如果您的json文件包含多个以下文件之一:

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

然后load()将失败。

我用自己的失败文件验证了这一点。

import json

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

之所以有效,是因为1_guests.json有一条记录[]。我正在使用all_guests.json的原始文件有6条记录,以换行符分隔。我删除了5条记录(我已经检查了它们是否包含在方括号中)并以新名称保存了该文件。然后,loads语句起作用了。

错误原为

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

PS。我使用记录一词,但这不是官方名称。另外,如果您的文件包含像我这样的换行符,则可以遍历整个文件,一次将一条记录加载到json变量中。


2
有没有办法json.loads读取以换行符分隔的json块?也就是说,表现得像[json.loads(x) for x in text.split('\n')]?相关:是否可以保证json.dumps在默认缩进的输出中不包含文字换行符?
2015年

1
@Ben,默认情况下json.dumps会将文本内容中的换行符更改为"\n",将json保留为一行。
jchook

7

好吧,这可能会对某人有所帮助。我的json文件像这样时我只是遇到了相同的错误

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

我发现它的格式不正确,所以我将其更改为

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

1
像您一样加载json.load(infile)
Akbar Noto

6

一线解决您的问题:

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

1
这不是一个通用的解决方案,它假设输入每行有一个JSON对象,并破坏了它没有的对象。
smci

3

如果您想用两种方法解决它,可以这样做:

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

1

我认为将字典保存在列表中并不是@falsetru提出的理想解决方案。

更好的方法是遍历字典并通过添加新行将其保存到.json。

我们的2本字典是

d1 = {'a':1}

d2 = {'b':2}

您可以将它们写入.json

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

而且您可以读取json文件而没有任何问题

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

简单高效


这不是一个通用的解决方案,它假设输入每行有一个JSON对象,并破坏了它没有的对象。
smci
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.