day3—数据提取
响应内容分类
结构化的响应内容
json字符串:可以使用re、json等模块来提取特定数据 xml字符串:可以用re、lxml等模块来提取特定数据 xml是一种可拓展性标记语言,专注于传输和数据存储。html用于数据显示。
非结构化响应内容
html字符串:可以使用re、lxml等模块来提取特定数据
常用的数据提取方式
jsonpath 模块
如果有一个多层嵌套的复杂字典,想要根据key和下标来批量提取value,这是比较困难的。jsonpath模块就能解决这个痛点,接下来我们就来学习jsonpath模块。安装方法:pip install jsonpath
语法规则 具体案例
from jsonpath import jsonpath
book_dict = {
"store": {
"book": [
{ "category": "reference",
"author": "Nigel Rees",
"title": "Sayings of the Century",
"price": 8.95
},
{ "category": "fiction",
"author": "Evelyn Waugh",
"title": "Sword of Honour",
"price": 12.99
},
{ "category": "fiction",
"author": "Herman Melville",
"title": "Moby Dick",
"isbn": "0-553-21311-3",
"price": 8.99
},
{ "category": "fiction",
"author": "J. R. R. Tolkien",
"title": "The Lord of the Rings",
"isbn": "0-395-19395-8",
"price": 22.99
}
],
"bicycle": {
"color": "red",
"price": 19.95
}
}
}
# 取响应值得title部分, 如果取不到将返回False
# 返回列表,如果取不到将返回False
print(jsonpath(book_dict,'$..title'))
jsonPath在网络中的应用
import requests
import json
import jsonpath
url = 'https:
headers = {"User-Agent": "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)"}
reponse = requests.get(url,headers=headers)
citylist = jsonpath.jsonpath(reponse.content.decode(),'$..')
with open('jsonPath.html','w') as f:
content = json.dumps(citylist,ensure_ascii= False)
f.write(content)
lxml模块
- lxml模块可以利用XPath规则语法,来快速的定位HTML\XML 文档中特定元素以及获取节点信息(文本内容、属性值)
- XPath (XML Path Language) 是一门在 HTML\XML 文档中查找信息的语言,可用来在 HTML\XML 文档中对元素和属性进行遍历。
- 提取xml、html中的数据需要lxml模块和xpath语法配合使用
谷歌浏览器xpath helper插件的安装和使用
xpath helper下载地址:见我博客上传资源 如果是linux或macOS操作系统,将压缩包后缀改为.crx,然后拖入已经开启开发者模式的浏览器扩展程序界面。
xpath的节点关系
每个html、xml的标签我们都称之为节点,其中最顶层的节点称为根节点。我们以xml为例,html也是一样的
- XPath 使用路径表达式来选取 XML 文档中的节点或者节点集。
- 这些路径表达式和我们在常规的电脑文件系统中看到的表达式非常相似。
- 使用chrome插件选择标签时候,选中时,选中的标签会添加属性class=“xh-highlight”
- 练习
http://www.itcast.cn/ 以传智官网为例子
- 选择所有的h2下的文本
- 获取所有的a标签的href
- 获取html下的head下的title的文本
- 获取html下的head下的link标签的href
/html/head/link/@href
节点修饰语法
路径表达式 | 结果 |
---|
//title[@lang=“eng”] | 选择lang属性值为eng的所有title元素 | /bookstore/book[1] | 选取属于 bookstore 子元素的第一个 book 元素。 | /bookstore/book[last()] | 选取属于 bookstore 子元素的最后一个 book 元素。 | /bookstore/book[last()-1] | 选取属于 bookstore 子元素的倒数第二个 book 元素。 | /bookstore/book[position()>1] | 选择bookstore下面的book元素,从第二个开始选择 | //book/title[text()=‘Harry Potter’] | 选择所有book下的title元素,仅仅选择文本为Harry Potter的title元素 | /bookstore/book[price>35.00]/title | 选取 bookstore 元素中的 book 元素的所有 title 元素,且其中的 price 元素的值须大于 35.00。 |
关于xpath的下标:
- 在xpath中,第一个元素的位置是1
- 最后一个元素的位置是last()
- 倒数第二个是last()-1
练习:
从itcast的页面中,选择所有学科的名称、第一个学科的链接、最后一个学科的链接:http://www.itcast.cn/ 以传智官网为例子。
- 所有的学科的名称
//div[@class="nav_txt"]//a[@class="a_gd"] - 第一个学科的链接
//div[@class="nav_txt"]/ul/li[1]/a/@href - 最后一个学科的链接
- `//div[@class=“nav_txt”]/ul/li[last()]/a/@href
其他节点选择语法
配符 | 描述 |
---|
* | 匹配任何元素节点。 | node() | 匹配任何类型的节点。 |
lxml模块的安装与使用示例
安装 pip/pip3 install lxml,lxml模块可以用于提取标签中的文本内容或者提取标签中的文本内容。 模块使用方法:
from lxml import etree
# '''封装等json格式'''
text = '''
<div>
<ul>
<li class="item-1">
<a href="link1.html">first item</a>
</li>
<li class="item-1">
<a href="link2.html">second item</a>
</li>
<li class="item-inactive">
<a href="link3.html">third item</a>
</li>
<li class="item-1">
<a href="link4.html">fourth item</a>
</li>
<li class="item-0">
a href="link5.html">fifth item</a>
</ul>
</div>
'''
# 利用etree.HTML,将html字符串(bytes类型或str类型)转化为Element对象,Element对象具有xpath的方法
element = etree.HTML(text)
# 获取li a的herf属性
li_name = element.xpath('//ul/li/a/@href')
# 获取li a的文本
ret_list = element.xpath('//ul/li/a/text()')
# zip可以实现共同遍历相同的集合
for name,el in zip( li_name,ret_list):
print(name,el)
___2022.04.12
|