2017-04-19 70 views
0

我一直在考虑的,我正在尝试加载到蟒蛇3.5如何加载与字符串包括

JSON文件加载双引号(“)json文件,我已经不得不做一些清洁。后续工作,消除双反斜线和额外的报价,但是我碰到的一个问题,我不知道如何解决

我运行下面的代码:

with open(filepath,'r') as json_file: 
    reader = json_file.readlines() 
    for row in reader: 
     row = row.replace('\\', '') 
     row = row.replace('"{', '{') 
     row = row.replace('}"', '}') 
     response = json.loads(row) 
     for i in response: 
       responselist.append(i['ActionName']) 

但是它扔了错误:

JSONDecodeError: Expecting ',' delimiter: line 1 column 388833 (char 388832) 

是造成这一问题的JSON的部分是下面的状态文本输入:

我加了换行来说明我的观点,它看起来像蟒蛇是不满,认为字符串包含双引号。

我有一种感觉,这可能与我用''替换字符串中的unicode字符替换'\'。有没有办法修复这些嵌套的字符串?我不介意StatusText字段是否被完全删除,我所追求的是ActionName字段的列表。

编辑: 我这里主持一个例子文件:

https://www.dropbox.com/s/1oanrneg3aqandz/2015-12-01T00%253A00%253A42.527Z_2015-12-01T00%253A01%253A17.478Z?dl=0

这是完全一样的,我收到,之前我已经更换了额外的反斜线和报价

这里是一个削减带有一个错误条目的样本的缩减版本

["{\"apiServerType\":0,\"RequestId\":\"52a65260-1637-4653-a496-7555a2386340\",\"StatusId\":0,\"StatusIdString\":\"Ok\",\"StatusText\":null,\"ActionName\":\"GetCameraImage\",\"Url\":\"http://mosi-prod.cloudapp.net/api/v1/GetCameraImage?AuthToken=vo*AB57XLptsKXf0AzKjf1MOgQ1hZ4BKipKgYl3uGew%7C&CameraId=13782\",\"Lat\":0.0,\"Lon\":0.0,\"iVendorId\":12561,\"iConsumerId\":2986897,\"iSliverId\":51846,\"UserId\":\"2986897\",\"HardwareId\":null,\"AuthToken\":\"vo*AB57XLptsKXf0AzKjf1MOgQ1hZ4BKipKgYl3uGew|\",\"RequestTime\":\"2015-12-01T00:00:42.5278699Z\",\"ResponseTime\":\"2015-12-01T00:01:02.5926127Z\",\"AppId\":null,\"HttpMethod\":\"GET\",\"RequestHeaders\":\"{\\\"Connection\\\":[\\\"keep-alive\\\"],\\\"Via\\\":[\\\"HTTP/1.1 nycnz01msp1ts10.wnsnet.attws.com\\\"],\\\"Accept\\\":[\\\"application/json\\\"],\\\"Accept-Encoding\\\":[\\\"gzip\\\",\\\"deflate\\\"],\\\"Accept-Language\\\":[\\\"en-us\\\"],\\\"Host\\\":[\\\"mosi-prod.cloudapp.net\\\"],\\\"User-Agent\\\":[\\\"Traffic/5.4.0\\\",\\\"CFNetwork/758.1.6\\\",\\\"Darwin/15.0.0\\\"]}\",\"RequestContentHeaders\":\"{}\",\"RequestContentBody\":\"\",\"ResponseBody\":null,\"ResponseContentHeaders\":\"{\\\"Content-Type\\\":[\\\"image/jpeg\\\"]}\",\"ResponseHeaders\":\"{}\",\"MiniProfilerJson\":null}"] 
+2

如果它的json,你不应该删除任何东西。如果你已经删除反斜杠......是不是反斜杠用于摆脱现在引起你的问题的引号? json将这些注释放在一边。如果你最终不喜欢解码,它可能是任何传递给JSON编码器的错误。 – tdelaney

+0

如何发布示例json文件,以便我们可以亲眼看到。 – tdelaney

+0

我已经添加了一个我已经收到的文件的例子的链接 –

回答

2

问题与您的想法有点不同。无论构建这些文件的程序如何使用已经被json编码的数据,并且结束了对一些信息的双倍甚至三倍编码。我在shell会话中将它剥离,并获得了可用的Python数据。你可以(1)去做那些编写构建这个热气腾腾的程序的嘟嘟啪啪啪......恩......和(2)手动扫描并解码内部的json字符串。

我解码的数据,这是一个字符串列表,但是这些字符串看上去很像JSON

>>> data = json.load(open('test.json')) 
>>> type(data) 
<class 'list'> 
>>> d0 = data[0] 
>>> type(d0) 
<class 'str'> 
>>> d0[:70] 
'{"apiServerType":0,"RequestId":"52a65260-1637-4653-a496-7555a2386340",' 

果然,我可以解码它

>>> d0_1 = json.loads(d0) 
>>> type(d0_1) 
<class 'dict'> 
>>> d0_1 
{'ResponseBody': None, 'StatusText': None, 'AppId': None, 'ResponseTime': '2015-12-01T00:01:02.5926127Z', 'HardwareId': None, 'RequestTime': '2015-12-01T00:00:42.5278699Z', 'StatusId': 0, 'Lon': 0.0, 'Url': 'http://mosi-prod.cloudapp.net/api/v1/GetCameraImage?AuthToken=vo*AB57XLptsKXf0AzKjf1MOgQ1hZ4BKipKgYl3uGew%7C&CameraId=13782', 'RequestContentBody': '', 'RequestId': '52a65260-1637-4653-a496-7555a2386340', 'MiniProfilerJson': None, 'RequestContentHeaders': '{}', 'ActionName': 'GetCameraImage', 'StatusIdString': 'Ok', 'HttpMethod': 'GET', 'iSliverId': 51846, 'ResponseHeaders': '{}', 'ResponseContentHeaders': '{"Content-Type":["image/jpeg"]}', 'apiServerType': 0, 'AuthToken': 'vo*AB57XLptsKXf0AzKjf1MOgQ1hZ4BKipKgYl3uGew|', 'iConsumerId': 2986897, 'RequestHeaders': '{"Connection":["keep-alive"],"Via":["HTTP/1.1 nycnz01msp1ts10.wnsnet.attws.com"],"Accept":["application/json"],"Accept-Encoding":["gzip","deflate"],"Accept-Language":["en-us"],"Host":["mosi-prod.cloudapp.net"],"User-Agent":["Traffic/5.4.0","CFNetwork/758.1.6","Darwin/15.0.0"]}', 'iVendorId': 12561, 'Lat': 0.0, 'UserId': '2986897'} 

采摘的条目之一,看起来像更多json

>>> hdrs = d0_1['RequestHeaders'] 
>>> type(hdrs) 
<class 'str'> 

是的,它解码为我想要的

>>> hdrs_0 = json.loads(hdrs) 
>>> type(hdrs_0) 
<class 'dict'> 
>>> 
>>> hdrs_0["Via"] 
['HTTP/1.1 nycnz01msp1ts10.wnsnet.attws.com'] 
>>> 
>>> type(hdrs_0["Via"]) 
<class 'list'> 
+0

如果他们仍然在公司里,他们现在会得到如此多的dope-slaps。问题是我有大约8000个这样的文件需要查看,所以通过字符串手动扫描是不可行的。我可以设置一个try语句来通过第二次解码来处理异常吗? –

+0

这些文件可能会遵循一个模式,一旦你发现了一个模式,你就会得到它们。否则,我会完全按照你的想法去做。遍历所有列表和字典,测试值是否是字符串,然后尝试'json.loads(value)'。你会得到一个'json.decoder.JSONDecodeError'来确保字符串保持字符串。 – tdelaney

+0

我已经发现所有不可读的文件都具有相同的actionName,而我之后的所有文件都是不同响应类型的计数。我设置了一个记录失败次数的try循环,并将其添加到我的结果中。我已经将这个答案标记为正确的洞察力。 –

0

给你:):

responselist = [] 
with open('dataFile.json','r') as json_file: 
    reader = json_file.readlines() 
    for row in reader: 
     strActNm = 'ActionName":"'; lenActNm = len(strActNm) 
     actionAt = row.find(strActNm) 
     while actionAt > 0: 
      nxtQuotAt = row.find('"',actionAt+lenActNm+2) 
      responselist.append(row[actionAt-1: nxtQuotAt+1]) 
      actionAt = row.find('ActionName":"', nxtQuotAt) 
print(responselist) 

这给:

>python3.6 -u "dataFile.py" 
['"ActionName":"GetTrafficTile"'] 
>Exit code: 0 

其中dataFile.json是上面提供您所提供的线上和dataFile.py代码文件。

这是一次艰苦的旅程,但如果文件格式不正确,则必须找到解决方法,并且无论如何都要找到简单的模式匹配。对于更复杂的情况,你将需要正则表达式(正则表达式),但在这种情况下,简单的.find()就足以完成这项工作。

该代码还会在行中找到多个“操作”(如果该行将包含多个操作)。

这里的结果对于在使用按照上述代码的小修改,你在你的链接提供的文件:

responselist = [] 
with open('dataFile1.json','r') as json_file: 
    reader = json_file.readlines() 
    for row in reader: 
     strActNm='\\"ActionName\\":\\"' 
     # strActNm = 'ActionName":"' 
     lenActNm = len(strActNm) 
     actionAt = row.find(strActNm) 
     while actionAt > 0: 
      nxtQuotAt = row.find('"',actionAt+lenActNm+2) 
      responselist.append(row[actionAt: nxtQuotAt+1].replace('\\','')) 
      actionAt = row.find('ActionName":"', nxtQuotAt) 
print(responselist) 

给出:

>python3.6 -u "dataFile.py" 
['"ActionName":"GetCameraImage"'] 
>Exit code: 0 

其中dataFile1.json为您提供的文件在链接中。