解析Json数据的几种方法
2018-01-06 20:55
411 查看
Json解析 |
key-value,某天你的leader让你去爬数据,你爬到了这样的数据:
var hei ha {‘error’: 0, ‘errorMsg’: ‘SUCCESS’, uptime: ‘20180105121318000’, ‘preClose’: 33.459999084473, tick: [{‘date’: ‘20180105’, ‘time’: 113002000, ‘price’: 33.990001678467, ‘volume’: 37100, ‘bsflag’: “B”, “ccl”: 0}…]};
既有单引号又有双引号,且单引号在属性和值之间交叉,怎么搞?replace?sub?再一看一个词包含另一个词,如,uptime与time,error与errorMsg,再替换?还有很多呢?心态要崩。。。。
这就崩了?实际的爬虫中很多大网站都是这样的json串,如,百度,新浪等。
不怕,总会有人帮我们写好工具的[奸诈笑],只需import就好了,实在满足不了个性化需求就改改源码。。。
以下将介绍解析json的四个库;
完整示例代码:完整示例下载;
环境:
OS:win10;
Python:3.6;
一、内置json模块 |
如果你是用Anaconda环境,会自带json模块。
自带的json模块对json数据的格式要求比较严格,要求:
必须出入str字段;
属性必须使用双引号
""括起来,如,
{["key": value, "a": b]}。
[b]♣ json模块的使用[/b]
示例1.1
使用标准数据格式。
import json str1 = 'jQuery180({"errorNo": 0, "errorMsg": "SUCCESS", "latestTimelineStamp": "20180105121318000", "preClose": 33.459999084473, "tick": [{"date": 20180105, "time": 113002000, "price": 33.990001678467, "volume": 37100, "bsflag": "B", "ccl": 0}]});' # 去除两边的无用数据 json_str1 = str1.strip("jQuery180();") # 解析json字符串 json_data1 = json.loads(json_str1) print("解析后的json数据:\n", json_data1) print("取json数据:\n", json_data1['tick'])
运行结果:
解析后的json数据: {'errorNo': 0, 'errorMsg': 'SUCCESS', 'latestTimelineStamp': '20180105121318000', 'preClose': 33.459999084473, 'tick': [{'date': 20180105, 'time': 113002000, 'price': 33.990001678467, 'volume': 37100, 'bsflag': 'B', 'ccl': 0}]} 取json数据: [{'date': 20180105, 'time': 113002000, 'price': 33.990001678467, 'volume': 37100, 'bsflag': 'B', 'ccl': 0}]
示例1.2
当数据中出现单引号时。
import json str1 = "{'errorNo': 0, 'errorMsg': 'SUCCESS', 'latestTimelineStamp': '20180105 cfc3 121318000', 'preClose': 33.459999084473, 'tick': [{'date': 20180105}]}" # 解析json字符串 json_data1 = json.loads(str1) print("解析后的json数据:\n", json_data1) print("取json数据:\n", json_data1['tick'])
运行结果:
JSONDecodeError Traceback (most recent call last) ... JSONDecodeError: Expecting property name enclosed in double quotes: line 1 column 2 (char 1)
报错!
属性名称没有使用双引号,所以,并不好用嘛。下面介绍另一个json解析神器-Demjson。Demjson就可以自适应的解决这些问题。
二、Demjson模块 |
Demjson模块,由Deron Meranda开发,demjson主页;
demjson使用标准python库,不用再安装其他依赖模块;
demjson读取数据依然使用冒号做识别,要求json串中的引号必须成对出现。
[b]♣ demjson安装[/b]
简易安装:
pip install demjson
源码安装:
下载demjson:demjson下载地址;
cd demjson文件目录
python setup.py install
[b]♣ demjson使用[/b]
示例2.1
带有单引号的json串;
import demjson str1 = "{'errorNo': 0, 'errorMsg': 'SUCCESS', 'latestTimelineStamp': '20180105121318000', 'preClose': 33.459999084473, 'tick': [{'date': 20180105, 'time': 113002000, 'price': 33.990001678467, 'volume': 37100, 'bsflag': 'B', 'ccl': 0}]}" json_data1 = demjson.decode(str1) print("解析后的json数据:\n", json_data1) print("取json数据:\n", json_data1['tick'])
运行结果:
解析后的json数据: {'errorNo': 0, 'errorMsg': 'SUCCESS', 'latestTimelineStamp': '20180105121318000', 'preClose': 33.459999084473, 'tick': [{'date': 20180105, 'time': 113002000, 'price': 33.990001678467, 'volume': 37100, 'bsflag': 'B', 'ccl': 0}]} 取json数据: [{'date': 20180105, 'time': 113002000, 'price': 33.990001678467, 'volume': 37100, 'bsflag': 'B', 'ccl': 0}]
成功搞定单引号。
示例2.2
字符串中属性或值带有单引号或双引号,且还有的属性不带有引号。
import demjson str1 = '''{'errorNo': 0, errorMsg: 'SUCCESS', "latestTimelineStamp": '20180105121318000', 'preClose': 33.459999084473, 'tick': [{'date': 20180105, 'time': 113002000, 'price': 33.990001678467, 'volume': 37100, 'bsflag': 'B', 'ccl': 0}]}''' json_data1 = demjson.decode(str1) print("解析后的json数据:\n", json_data1) print("取json数据:\n", json_data1['tick'])
运行结果:
解析后的json数据: {'errorNo': 0, 'errorMsg': 'SUCCESS', 'latestTimelineStamp': '20180105121318000', 'preClose': 33.459999084473, 'tick': [{'date': 20180105, 'time': 113002000, 'price': 33.990001678467, 'volume': 37100, 'bsflag': 'B', 'ccl': 0}]} 取json数据: [{'date': 20180105, 'time': 113002000, 'price': 33.990001678467, 'volume': 37100, 'bsflag': 'B', 'ccl': 0}]
面对单引号,双引号,没有引号,demjson依然能够解决问题,Damn good~ 哈哈♥♥
示例2.3
当json串中包含其他情况呢?如本文开头的那种糟糕情况,如,当json数据前包含一段其他代码,这可以使用strip去除,缺少单引号或双引号,demjson行吗?
import demjson str1 = '''{errorNo': 0, errorMsg: 'SUCCESS', "latestTimelineStamp": '20180105121318000', 'preClose': 33.459999084473, 'tick': [{'date': 20180105, 'time': 113002000, 'price': 33.990001678467, 'volume': 37100, 'bsflag': 'B', 'ccl': 0}]}''' json_data1 = demjson.decode(str1) print("解析后的json数据:\n", json_data1) print("取json数据:\n", json_data1['tick'])
运行结果:
解析后的json数据: Traceback (most recent call last): ... demjson.JSONDecodeError: Missing value for object property, expected ":"
demjson以冒号做分割,去匹配单引号或双引号识别属性和值;
当没有匹配上时,以冒号作为分割得到属性和值;
而面对这样的状况,demjson也是心累了,无能为力了,爱不动了…难道就到这里了吗?不,还有jsonlike,依然稀饭内。
三、jsonlike模块 |
诚然,当json数据前包含一段其他代码,这可以使用strip去除,但如本文开头的那种糟糕情况,如,缺少单引号或双引号,替换?当json串很大且情况复杂时要替换到何时?发现错就替换一次?当你使用网站API满怀兴奋地拿到10000多条json数据时,你确定要自己替换???
曾几何时,当我碰到这种情况时,我选择了替换,那是个心酸心累的夜晚,一个人,替换这见鬼的不规则的字符,心中无数cn马奔腾。。。
去Google一下“the most powerful modules for json in python”,然而,并没有得到什么,试着搜索了其他,也没有什么,自己在pypi上搜json,发现一个玩意叫做
jsonlike,听名字感觉这就是我要的啊,像json?ok,试试。
[b]♣ jsonlike简介[/b]
jsonlike由Shaun Viguerie开发,github地址;
功能强大,可解析 类json串;
但需要安装依赖模块:
demjson==2.2.4
unwrapper==1.0.0
nose
sure
pyyaml
[b]♣ 安装jsonlike模块[/b]
简易安装:
pip install jsonlike
源码安装:
下载demjson:demjson下载地址;
cd demjson文件目录
python setup.py install
注意安装依赖模块。
[b]♣ 使用jsonlike[/b]
示例3.1
字符串中属性或值带有单引号或双引号,且还有的属性不带有引号。此时,使用json.loads()会调用demjson。
import jsonlike str1 = '''{'errorNo': 0, errorMsg: 'SUCCESS', "latestTimelineStamp": '20180105121318000', 'preClose': 33.459999084473, 'tick': [{'date': 20180105, 'time': 113002000, 'price': 33.990001678467, 'volume': 37100, 'bsflag': 'B', 'ccl': 0}]}''' json_data1 = jsonlike.loads(str1) print("解析后的json数据:\n", json_data1) print("取json数据:\n", json_data1['tick'])
运行结果:
解析后的json数据: {'errorNo': 0, 'errorMsg': 'SUCCESS', 'latestTimelineStamp': '20180105121318000', 'preClose': 33.459999084473, 'tick': [{'date': 20180105, 'time': 113002000, 'price': 33.990001678467, 'volume': 37100, 'bsflag': 'B', 'ccl': 0}]} 取json数据: [{'date': 20180105, 'time': 113002000, 'price': 33.990001678467, 'volume': 37100, 'bsflag': 'B', 'ccl': 0}]
可以看出,jsonlike能够正确处理。
示例3.2
json串各种糟糕,且单引号和双引号不对称,json数据外还有一些无用字符;这时,jsonlike.loads()便无能为力,需要使用另一个方法unwrap_and_load。
import jsonlike str1 = '''var hei ha {'error': 0, 'errorMsg': 'SUCCESS', uptime: '20180105121318000', 'preClose': 33.459999084473, tick: [{'date': '20180105', 'time': 113002000, 'price': 33.990001678467, 'volume': 37100, 'bsflag': "B", "ccl": 0}]};''' json_data1 = jsonlike.unwrap_and_load(str1) print("解析后的json数据:\n", json_data1) print("取json数据:\n", json_data1['tick'])
运行结果:
解析后的json数据: {'error': 0, 'errorMsg': 'SUCCESS', 'uptime': '20180105121318000', 'preClose': 33.459999084473, 'tick': [{'date': '20180105', 'time': 113002000, 'price': 33.990001678467, 'volume': 37100, 'bsflag': 'B', 'ccl': 0}]} 取json数据: [{'date': '20180105', 'time': 113002000, 'price': 33.990001678467, 'volume': 37100, 'bsflag': 'B', 'ccl': 0}]
可以看出,’jsonlike.unwrap_and_load()`帮我们做了很多脏活累活,Damn Damn good~
总结 |
值得注意的是三个模块在适用性和效率上各不相同:
1. json处理规整数据的效率较高;
2. demjson处理json数据效率不高,甚至是慢;
3. jsonlike处理效率与demjson类似;
此外,还有simplejson等模块,再讲simplejson有点不伦不类,如果simplejson不引入C库,那么效率也是较差的。
json数据 | 适用模块 |
---|---|
格式规整 | 内置json |
格式不规整,但引号无缺失 | demjson |
格式不规整,引号缺失,json串前后有其他字符 | jsonlike |
能力有限,欢迎指错交流;
欢迎关注个人微信公众号WaltSmithML或新浪微博WaltSmith,公众号提供机器学习、深度学习、Hadoop、Spark、Python、数学知识等免费视频教程。本人主要方向为机器学习和深度学习。非常欢迎一起交流学习哈,除了学习,还可免费帮忙download论文或者书籍哈==============
♥♥♥微信公众号♥♥♥
♥♥♥♥
♥♥新浪微博♥♥
相关文章推荐
- Android基础之json数据的几种解析方法
- Android--解析Json格式数据的几种方法
- Android解析json数据的几种方法
- 【VBA研究】解析JSON数据的几种方法
- 简单直接的方法解析JSON数据
- Java构造和解析Json数据的两种方法详解二
- C# JavaScriptSerializer 解析Json数据(多方法解析Json 三)
- iOS中解析json格式数据的各种方法调用
- 在JavaScript中将JSON的字符串解析成JSON数据格式的两种方法
- Java构造和解析Json数据的两种方法详解
- PHP输出json数据时中文不进行unicode编码的几种方法总结
- JSON三种数据解析方法
- Python解析JSON数据的基本方法
- Java构造和解析Json数据的两种方法详解二
- 用安卓自带的原生方法解析从webservice获取的json数据
- 用jquery解析JSON数据的方法(转)
- Gson解析JSON数据中动态未知字段key的方法
- Java构造和解析Json数据的两种方法详解2
- Java构造和解析Json数据的两种方法详解2