如何使用包含双引号 (") 的字符串加载 json 文件
How to load a json file with strings including double quotes (")
我收到了 JSON 文件的负载,我正在尝试将这些文件加载到 python 3.5
我已经不得不做一些清理工作,删除双反斜杠和额外的引号,但是我 运行 遇到了一个我不知道如何解决的问题。
我正在运行宁以下代码:
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 字段的列表。
编辑:
我在这里托管了一个示例文件:
这与我收到的完全一样,在我替换多余的反斜杠和引号之前
这是示例的简化版本,其中有一个错误条目
["{\"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}"]
问题和你想的有点不一样。无论使用什么程序构建这些文件,都使用已经 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'>
给你 :) :
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
是上面提供的代码。
这是艰难的旅程,但如果文件格式不正确,您必须找到解决方法,并且在任何情况下都可以使用简单的模式匹配。对于更复杂的情况,您将需要 regex(正则表达式),但在这种情况下,一个简单的 .find()
就足以完成这项工作。
该代码还在该行中找到多个 "actions"(如果该行包含多个操作)。
这里是您在 link 中提供的文件的结果,同时对上面的代码进行了以下小修改:
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 是您在 link 中提供的文件。
我收到了 JSON 文件的负载,我正在尝试将这些文件加载到 python 3.5
我已经不得不做一些清理工作,删除双反斜杠和额外的引号,但是我 运行 遇到了一个我不知道如何解决的问题。
我正在运行宁以下代码:
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 字段的列表。
编辑: 我在这里托管了一个示例文件:
这与我收到的完全一样,在我替换多余的反斜杠和引号之前
这是示例的简化版本,其中有一个错误条目
["{\"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}"]
问题和你想的有点不一样。无论使用什么程序构建这些文件,都使用已经 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'>
给你 :) :
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
是上面提供的代码。
这是艰难的旅程,但如果文件格式不正确,您必须找到解决方法,并且在任何情况下都可以使用简单的模式匹配。对于更复杂的情况,您将需要 regex(正则表达式),但在这种情况下,一个简单的 .find()
就足以完成这项工作。
该代码还在该行中找到多个 "actions"(如果该行包含多个操作)。
这里是您在 link 中提供的文件的结果,同时对上面的代码进行了以下小修改:
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 是您在 link 中提供的文件。