2017-04-19 139 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爲您提供的文件在鏈接中。

相關問題