之前的文章我们已经可以根据 re 模块, Xpath 模块和 BeautifulSoup4 模块来爬取网站上我们想要的数据并且存储在本地, 但是我们并没有对存储数据的格式有要求, 本章我们就来看数据的存储格式 JSON 及 Python 中的 JSON 模块.
JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式, 它使得人们很容易的进行阅读和编写. 同时也方便了机器进行解析和生成. 适用于进行数据交互的场景, 比如网站前台与后台之间的数据交互.
JSON 和 xml 的比较可谓不相上下.
Python 中自带了 JSON 模块, 直接 import JSON 就可以使用了.
官方文档: http://docs.python.org/library/json.html
JSON 在线解析网站: http://www.json.cn/#
JSON 简单说就是 JavaScript 中的对象和数组, 所以这两种结构就是对象和数组两种结构, 通过这两种结构可以表示各种复杂的结构
对象: 对象在 JS 中表示为 { } 括起来的内容, 数据结构为 { key:value, key:value, ... }的键值对的结构, 在面向对象的语言中, key 为对象的属性, value 为对应的属性值, 所以很容易理解, 取值方法为 对象. key 获取属性值, 这个属性值的类型可以是数字, 字符串, 数组, 对象这几种.
数组: 数组在 JS 中是中括号 [ ] 括起来的内容, 数据结构为 ["Python", "javascript", "C++", ...], 取值方式和所有语言中一样, 使用索引获取, 字段值的类型可以是 数字, 字符串, 数组, 对象几种.
Python 中 JSON 模块提供了四个功能: dumps,dump,loads,load, 用于字符串 和 python 数据类型间进行转换.
1. JSON.loads()
把 JSON 格式字符串解码转换成 Python 对象 从 JSON 到 python 的类型转化对照如下:
- import JSON
- strList = '[1, 2, 3, 4]'
- strDict = '{"city":" 北京 ","name":" 大猫 "}'
- print(JSON.loads(strList)) # [1, 2, 3, 4]
- print(JSON.loads(strDict)) # {'city': '北京', 'name': '张三'}
- 2. JSON.dumps()
实现 python 类型转化为 JSON 字符串, 返回一个 str 对象 把一个 Python 对象编码转换成 JSON 字符串
从 python 原始类型向 JSON 类型的转化对照如下:
- import JSON
- listStr = [1, 2, 3, 4]
- tupleStr = (1, 2, 3, 4)
- dictStr = {"city": "北京", "name": "张三"}
- print(JSON.dumps(listStr)) # '[1, 2, 3, 4]'
- print(JSON.dumps(tupleStr)) # '[1, 2, 3, 4]'
- print(JSON.dumps(dictStr)) # '{"city":"\u5317\u4eac","name":"\u5f20\u4e09"}'
- 3. JSON.dump()
将 Python 内置类型序列化为 JSON 对象后写入文件
- import JSON
- listStr = [{"city": "北京"}, {"name": "张三"}]
- JSON.dump(listStr, open("listStr.json", "w"))
- dictStr = {"city": "北京", "name": "李四"}
- JSON.dump(dictStr, open("dictStr.json", "w"), ensure_ascii=False) # 添加参数 ensure_ascii=False 禁用 ascii 编码, 按 utf-8 编码
输出结果:
4. JSON.load()
读取文件中 JSON 形式的字符串元素 转化成 python 类型
- import JSON
- strList = JSON.load(open("listStr.json"))
- print(strList) # [{'city': '北京'}, {'name': '张三'}]
- strDict = JSON.load(open("dictStr.json"))
- print(strDict) # {'city': '北京', 'name': '李四'}
- JsonPath
JsonPath 是一种信息抽取类库, 是从 JSON 文档中抽取指定信息的工具, 提供多种语言实现版本, 包括: JavaScript, Python, PHP 和 Java.
JsonPath 对于 JSON 来说, 相当于 XPATH 对于 xml.
下载地址: https://pypi.python.org/pypi/jsonpath/
安装方法: 点击 Download URL 链接下载 jsonpath, 解压之后执行 python setup.py install
官方文档: http://goessner.net/articles/JsonPath/
JsonPath 与 XPath 语法对比:
JSON 结构清晰, 可读性高, 复杂度低, 非常容易匹配, 下表中对应了 XPath 的用法.
XPath | JSONPath | 描述 |
---|---|---|
/ | $ | 根节点 |
. | @ | 现行节点 |
/ | .or[] | 取子节点 |
.. | n/a | 取父节点,Jsonpath 未支持 |
// | .. | 就是不管位置,选择所有符合条件的条件 |
* | * | 匹配所有元素节点 |
@ | n/a | 根据属性访问,Json 不支持,因为 Json 是个 Key-value 递归结构,不需要。 |
[] | [] | 迭代器标示(可以在里边做简单的迭代操作,如数组下标,根据内容选值等) |
| | [,] | 支持迭代器中做多选。 |
[] | ?() | 支持过滤操作. |
n/a | () | 支持表达式计算 |
() | n/a | 分组,JsonPath 不支持 < br ztid="150" ow="0" oh="0"> |
示例:
我们以拉勾网城市 JSON 文件 https://www.lagou.com/lbs/getAllCitySearchLabels.json 为例, 获取所有城市.
- import urllib.request
- import JSON
- import jsonpath
- import ssl
- # 取消代理验证
- ssl._create_default_https_context = ssl._create_unverified_context
- url = 'https://www.lagou.com/lbs/getAllCitySearchLabels.json'
- headers = {
- "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_3) ApplewebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36"}
- # 发送请求
- request = urllib.request.Request(url, headers=headers)
- response = urllib.request.urlopen(request)
- HTML = response.read().decode("utf-8")
- # 把 JSON 格式字符串转换成 python 对象
- jsonobj = JSON.loads(HTML)
- # 从根节点开始, 匹配 name 节点
- citylist = jsonpath.jsonpath(jsonobj, '$..name')
- fp = open('city.json', 'w')
- content = JSON.dumps(citylist, ensure_ascii=False)
- fp.write(content)
- fp.close()
程序启动后会在本地生成一个 city.JSON 的文件, 结果如下:
来源: https://www.cnblogs.com/weijiutao/p/10881893.html