如何加载包含双引号 (") 的字符串的 json 文件



我已经给了我试图加载到python 3.5

的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的一部分是以下状态文本条目:

"StatusId":8,
"StatusIdString":"UnknownServiceError",
"StatusText":"u003cCompany docTypeu003d"Mobile.Tile" statusIdu003d"421" statusTextu003d"Start time of 11/30/2015 12:15:00 PM is more than 5 minutes in the past relative to the current time of 12/1/2015 12:27:01 AM." copyrightu003d"Copyright Company Inc." versionNumberu003d"7.3" createdDateu003d"2015-12-01T00:27:01Z" responseIdu003d"e74710c0-dc7c-42db-b608-bf905d95d153" /u003e",
"ActionName":"GetTrafficTile"

我添加了线路休息以说明我的观点,看来Python对字符串包含双引号感到不高兴。

我有一种感觉,这可能与我的替换" '"与字符串中的Unicode字符混乱有关。有什么方法可以修复这些嵌套弦?我不介意是否完全删除了statustext字段,我所追求的只是ActionName字段的列表。

编辑:我在这里托管了一个示例文件:

https://www.dropbox.com/s/1oanrneg3aqandz/2015-12-01T00%3A00%3A42.527Z_2015-12-01T00;

这与我收到的完全一样,在更换额外的后斜切和报价之前

这是一个不良条目的样本的削减版本

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

问题与您想象的有点不同。无论哪种程序构建这些文件,都使用了已经编码的数据,最终将两倍,甚至三重编码编码一些信息。我在外壳会话中将其分开,并获得了可用的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'>

在这里你是:):

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是您在链接中提供的文件。

最新更新