我有一个巨大的json文件要转移到csv。我在互联网上搜索了很多,我自己也尝试编写Python,但没有任何作用。我被困在这里一个星期。有人可以帮我吗? json文件格式为:
{"Gid": "5999043768223797248",
"rights": [{"grantorContext": "Freemium right added by Netlife", "sku": "CMO-STO-2-FREE", "rightId": "5340e29a6dc01000", "grantorId": "NETLIFE_B2C"}],
"used_quota": "16.95",
"creationtime": "2001-04-29 12:58:33",
"devices": [{"last_connection": "2001-05-30 22:06:08", "os_version": "4.2.2", "auto_upload": "wifi", "last_upload": "2002-04-29 13:12:26", "device_name": "i-mobile i-STYLE 7.5", "platform": "unknow", "client_version": "2.0.0"}],
"total_quota": 2.0,
"Uid": ["666927729520"]}
{"Gid": "5999043740151320576",
"rights": [{"grantorContext": "Freemium right added by Netlife", "sku": "CMO-STO-2-FREE", "rightId": "5340e29f72c05000", "grantorId": "NETLIFE_B2C"},
{"grantorContext": null, "sku": "CMO-STO-25-M", "rightId": "53b5d2d8b0400000", "grantorId": "DTN"}],
"used_quota": "480.85",
"creationtime": "2001-04-29 12:58:38",
"devices": [{"last_connection": "2001-08-02 03:46:05", "os_version": "8.4", "auto_upload": "wifi", "last_upload": "2015-08-02 03:46:05", "device_name": "Nokia", "platform": "unknow", "client_version": "1.0.0"}],
"total_quota": 27.0,
"Uid": ["465949097714"]}
{"Gid": "5999043675907166208",
"rights": [{"grantorContext": null, "sku": "CMO-STO-25-M", "rightId": "53b5d2e161000000", "grantorId": "DTN"},
{"grantorContext": "Freemium right added by Netlife", "sku": "CMO-STO-2-FREE", "rightId": "5340e29b42805000", "grantorId": "NETLIFE_B2C"}],
"used_quota": "8.26",
"creationtime": "2001-04-29 12:58:35",
"devices": [{"last_connection": "2001-04-29 13:08:24", "os_version": "4.2.2", "auto_upload": "wifi", "last_upload": "2002-04-29 13:03:25", "device_name": "Nokia V797", "platform": "unknow", "client_version": "2.0.0"}],
"total_quota": 27.0,
"Uid": ["666994575443"]}
答案 0 :(得分:0)
我自己也有类似的文件!
它不是有效的JSON文件。它是一组连接成一个的JSON文件。来自python json.dumps文档
与pickle和marshal不同,JSON不是框架协议,所以试图 使用重复调用dump()来序列化多个对象 相同的fp将导致无效的JSON文件
这意味着即使它一次全部适合内存,也不能使用json.load来读取此文件,除非您在第一行之前编辑“[”并在结尾处编辑“]”每个元素之间的逗号(即“}”和“{”之间的空行
您可以使用python json模块进行操作并让它按照我认为您想要的方式进行操作,将每组七个元素按顺序读取为带有“Gid”“权限”键等的python dict。
你必须使用JSONDecoder类的raw_decode方法,该方法将在结束时停止“}”并将索引返回到它正在扫描的字符串中,这样你就可以砍掉它刚刚处理过的字符串。
因此,读取一个大块文件的大块,并在异常处理程序中尝试raw_decode一个元素。如果成功,保存解码结果,删除已成功解码的部分,然后重复。如果出现异常,请从文件中读取另一个块并附加到要解码的字符串并重复。如果仍然出现异常,那么您所在的JSON元素已损坏(或者比块大小更长,或者您无法正确处理文件末尾)。
如果您的文件小于几十(几百?)Mbytes,则编码要容易得多。然后,只需将整个事物读入一个字符串并开始从它前面扼杀JSON元素,直到除了空白之外什么都没有,或者直到你遇到解码器错误。
答案 1 :(得分:0)
这是一种蛮力的方式,因为当文件小到可以作为单个字符串处理而没有内存不足时
import json
import re
multijsons = open('file.json','r').read()
sep = re.compile( r'\}\s*\{' )
jsonlist = '[' + re.sub( sep, '}, {', multijsons ) + ']'
load = json.loads( jsonlist)
# quick debug:
for item in load:
print item
print '\n---\n'
这是我使用的,因为我的文件不是那么大。考虑编码以上但不需要它,看起来好像很棘手
答案 2 :(得分:0)
这里使用re.split()
稍微不那么蛮力的方式我已经测试了以下在带有8Gb RAM的core-i3上仅需几秒钟
huge="{" + "a"*1000 + "}\n"
huge = huge * 500000
len(huge)/1000000.0
# get 501.5 (Mbytes)
jsons = re.split(r'\}\s*\{', huge)
len(s)
# get 500000, took about 2 seconds
del huge # might be a good idea to free half a gigabyte asap.
split生成各个JSON元素,每个元素都在自己的字符串中,减去开放的大括号(第一个除外)和close卷曲(除了最后一个)。所以剩下的工作(未经测试)将是
jsons[0] = jsons[0] + '}'
n = len(jsons)
jsons[n-1] = '{' + jsons[n-1]
for i in range( 1, n-1 ): jsons[i] = '{' + jsons[i] + '}'
# i'd anticipate another couple of seconds to get here
for j in jsons:
data = json.load( j)
# do whatever with data
# will take as long as it's going to take ....