解决json解析失败报错:json.decoder.JSONDecodeError
最近遇到一个json字符串解析失败的问题,原因是json里面的":这个两个符合和一些特殊符号在搞鬼,报错如下:
json.decoder.JSONDecodeError: Expecting property name enclosed in double quotes: …
json.decoder.JSONDecodeError: Expecting ‘,’ delimiter: …
json.decoder.JSONDecodeError: Expecting ‘:’ delimiter: …
前提是符合json字符串的格式:
# 最容易犯的错误,以下只有一个是json字符串的标准格式
# 符合json字符串
'{"name":"zhangsan","age":"17","email":"123@163.com"}'
# 不符合json字符串
"{'name':'zhangsan','age':'17','email':'123@163.com'}"
请对号入座,废话不多说,直接上代码,可以直接使用:
# coding=utf-8
import json
import re
import sys
sys.setrecursionlimit(1000000)
def deal_json_invaild(text):
if type(text) != str:
raise Exception("参数接受的是字符串类型")
# text = re.search(r"\{.*\}", text).group()
text = re.sub(r"\n|\t|\r|\r\n|\n\r|\x08|\\", "", text)
try:
json.loads(text)
except json.decoder.JSONDecodeError as err:
temp_pos = int(re.search(r"\(char (\d+)\)", str(err)).group(1))
temp_list = list(text)
while True:
if temp_list[temp_pos] == "\"" or "}":
if temp_list[temp_pos - 1] == "{":
break
elif temp_list[temp_pos - 1] == (":" or "{") and temp_list[temp_pos - 2] == ("\"" or ":" or "["):
break
elif temp_list[temp_pos] == "|\n|\t|\r|\r\n|\n\r| ":
temp_list[temp_pos] = re.sub(temp_list[temp_pos], "", temp_list[temp_pos])
text = "".join(temp_list)
elif temp_list[temp_pos] == "\"":
temp_list[temp_pos] = re.sub(temp_list[temp_pos], "“", temp_list[temp_pos])
text = "".join(temp_list)
elif temp_list[temp_pos] == "}":
temp_list[temp_pos - 1] = re.sub(temp_list[temp_pos], "\"", temp_list[temp_pos])
text = "".join(temp_list)
temp_pos -= 1
temp_pos -= 1
return deal_json_invaild(text)
else:
return text
if __name__ == '__main__':
# 测试字符串
text = '"sadasd""{""name":"张三","age":24,"电话":1008611,"地址":"中国","武当山"}""""saddsd'
a = deal_json_invaild(text)
print(json.loads(a))
注意:测试字符串地方必须是符合json转换规则的,如:’{“name”:“张三”,“age”:24,“电话”:1008611}’,注意单引号和双引号的使用,因为网上爬取下来的字符串也是这种格式的。我再处理之前想清洗了数据,即把"\n|\t|\r|\r\n|\n\r|\"这些给他去除掉,不然会影响json解析。
以上代码对json字符串解析失败处理方法,能解决95%以上的问题,还有5%可能自己还没遇到过奇葩字符串。之前有遇到一个非常奇怪的字符导致解析失败,就是上面代码中的:
text = re.sub(r"\n|\t|\r|\r\n|\n\r|\x08|\\", "", text)
看到没有,我把"\x08"给替换了,这个编码在正常打印的时候是不会输出到控制台的,非常隐蔽,但是json解析的时候他又占字节,所以导致解析失败。解决这种方法,博主是采用:把原内容用切割的方式转换为列表,再结合json解析抛出异常的位置,打印出来异常字符串附近的字符(列表形式),就可以看到异常的字符串了,再把它去除掉就行了。
有什么新的处理方法记得给我留言哈~
————————————————————————————————————————
补充更新,最近太忙了,博客都来不及更新,再这里补充一个今天遇到的上边解决不了的错误,上截图:
奇怪的是我拿到json.cn是可以解析出来json字符串的,很纳闷。
解决办法:
就是先把我之前的字符串dumps后再解析就可以了。