=Start=
缘由:
最近接手维护同事写的一段代码,大的问题没有,但是小的、隐藏的问题不断,其中一类经常出现的就是json.loads()导致的各种异常。虽然之前我在blog中也整理了不少解析json的文章,但是,这次还是忍不住再做一个整理,为后续自己在用Python做json解析提供一个实际可参考的标准。
正文:
参考解答:
一、常碰到的几种错误类型
ValueError: Expecting property name enclosed in double quotes: line 1 column 2 (char 1) ValueError: Invalid \escape ValueError: Expecting property name: line 1 column 2 (char 1) ValueError: Expecting , delimiter: line 1 column 50 (char 49)
二、对应的临时解决办法
错误类型: ValueError: Expecting property name enclosed in double quotes: line 1 column 2 (char 1) 错误原因: 不是合法的json格式(name需要用「双引号」包裹) 解决办法: .replace("'", '"')
&
错误类型: ValueError: Invalid \escape 错误原因: 输入的字符串存在编码、转义问题 解决办法: import re regex = re.compile(r'\\(?![/u"])') fixed = regex.sub(r"\\\\", original) # https://stackoverflow.com/questions/9312196/how-to-convert-this-string-into-json-format-using-json-loads
&
错误类型: ValueError: Expecting property name: line 1 column 2 (char 1) 错误原因: 单引号、单引号前面的字符u 解决办法: .replace("u'", "'") # https://stackoverflow.com/questions/25707558/json-valueerror-expecting-property-name-line-1-column-2-char-1 # https://stackoverflow.com/questions/4033633/handling-lazy-json-in-python-expecting-property-name
&
错误类型: ValueError: Expecting , delimiter: line 1 column 50 (char 49) 错误原因: 输入的不是合法的json字符串 解决办法: .replace("\\", r"\\") # https://stackoverflow.com/questions/28223242/python-json-loads-valueerror-expecting-delimiter
三、根本的错误原因
- 传递给 json.loads() 函数的不是合法的json格式字符串!!!
- 传递给 json.loads() 函数的不是合法的json格式字符串!!!
- 传递给 json.loads() 函数的不是合法的json格式字符串!!!
看看合法的json字符串和Python的dict的区别:
json | Python-dict |
---|---|
只能用双引号包裹字符串 | 单引号和双引号都可以包裹字符串 |
json 可以是这样子[{"name": "x"},{"age": 2}] |
在Python中 [{"name": "x"},{"age": 2}] 叫列表里面有2个字典的元素 |
如果Python中的字典中都是用双引号来包裹字符串的,json.loads()才可以解析 | 但Python可以把json数据直接当成字典或者列表使用 |
四、引发的一些思考和规范
如果必须要对传入的内容进行解析,且格式较为可控,可以通过常规字符串替换、正则匹配替换将字符串转换成合法的json格式。
临时解决办法(自己处理): 非法的json字符串,想要用 json.loads() 去解析的话,还是很麻烦的,要自己处理后,确保合法,才可以。
&
如果对传入的内容不可控,最合理的做法是将json.loads()操作放入try..catch块,捕获出现的异常,记录无法正确解析的内容。这么做有2方面考虑:
- 不因为异常输入导致程序异常(放入try..catch块);
- 不因为程序异常导致数据丢失(加入logging机制);
合理解决办法(非合法不处理): try: # do some json.loads() operation catch Exception as e: logger.error(traceback.format_exc()) # do something else finally: # return/continue/pass
参考链接:
- http://json.org/json-zh.html
- https://docs.python.org/2/library/json.html
- https://stackoverflow.com/questions/25707558/json-valueerror-expecting-property-name-line-1-column-2-char-1
- https://stackoverflow.com/questions/4033633/handling-lazy-json-in-python-expecting-property-name
- https://stackoverflow.com/questions/9312196/how-to-convert-this-string-into-json-format-using-json-loads
- https://stackoverflow.com/questions/28223242/python-json-loads-valueerror-expecting-delimiter
- https://stackoverflow.com/questions/21058935/python-json-loads-shows-valueerror-extra-data
=END=
《 “Python中的json.loads()可能会出现哪些错误?” 》 有 4 条评论
python递归解析JSON(目前最好的方案)
https://blog.csdn.net/qq_17550379/article/details/80276477
Python实现递归解析json
https://blog.csdn.net/daqingwow/article/details/17993881
从零开始Python实现一个递归下降JSON解释器和生成器
https://github.com/EStormLynn/Python-JSON-Parser
题 通过嵌套json对python中的特定键进行递归迭代
http://landcareweb.com/questions/42710/tong-guo-qian-tao-jsondui-pythonzhong-de-te-ding-jian-jin-xing-di-gui-die-dai
如果有很多特殊字符,还有别的解决方案吗
指的是格式是合法的json,但内容存在多种特殊字符?内容的问题合理设置编解码应该就可以解决。
Python中 json 字符串内容中的 换行符
python why json value newline double escape char
https://stackoverflow.com/questions/42068/how-do-i-handle-newlines-in-json
https://stackoverflow.com/questions/31203259/python-write-valid-json-with-newlines-to-file
https://stackoverflow.com/questions/45570779/python-handling-newlines-in-json-load-vs-json-loads
`
需要用 \\n 来表示真实的换行符 \n ,即要添加一个转义符,否则会报错。
`