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

我正在从一个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
}
495296 次浏览

正如你在下面的例子中看到的,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]))
[{}, {}]

你可以从文件中读取,jsonifying每一行:

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

这避免了存储中间的python对象。只要你每次append()调用都写一个完整的tweet,这应该可以工作。

如果您的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"}]

然后loads()将失败。

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

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条记录(我已经用括号检查了它们),并将文件保存在一个新名称下。然后负载语句就工作了。

错误

   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变量中。

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

JSONDecodeError: Extra data: line 2 column 1

MongoDB JSON转储每行有一个对象,所以对我来说有用的是:

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

如果你想在两行代码中解决这个问题,你可以这样做:

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

针对您的问题的一句话:

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

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

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

我们的两本词典是

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文件是这样的

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

我的json文件的格式完全是问题中的一个,但没有一个解决方案在这里工作。最后,我在另一个Stackoverflow线程上找到了一个变通办法。因为这篇文章是谷歌搜索的第一个链接,我把答案放在这里,这样以后来这篇文章的人会更容易找到它。

如上所述,有效的json文件需要"["开头"]"在文件的末尾。此外,在每个json项后,不是"}"必须有"},"。所有括号不含引号!这段代码只是将格式错误的json文件修改为正确的格式。

https://stackoverflow.com/a/51919788/2772087 < a href = " https://stackoverflow.com/a/51919788/2772087 " > < / >

如果使用文件描述符的__abc1方法,则错误是由于__abc0符号…所以通过使用readlines()&但只是去掉这样的字符!

import json


path = # contains for example {"c": 4} also on multy-lines


new_d = {'new': 5}
with open(path, 'r') as fd:
d_old_str = fd.read().replace('\n', '') # remove all \n
old_d = json.loads(d_old_str)


# update new_d (python3.9 otherwise new_d.update(old_d))
new_d |= old_d
          

with open(path2, 'w') as fd:
fd.write(json.dumps(new_d)) # save the dictionary to file (in case needed)

... 如果你真的真的想使用readlines()这里有一个替代解决方案

new_d = {'new': 5}
with open('some_path', 'r') as fd:
d_old_str = ''.join(fd.readlines()) # concatenate the lines
d_old = json.loads(d_old_str)


# then as above

如果您的数据来自您无法控制的源,请使用此方法

def load_multi_json(line: str) -> [dict]:
"""
Fix some files with multiple objects on one line
"""
try:
return [json.loads(line)]
except JSONDecodeError as err:
if err.msg == 'Extra data':
head = [json.loads(line[0:err.pos])]
tail = FrontFile.load_multi_json(line[err.pos:])
return head + tail
else:
raise err