爬取网页后,我们想要的并不是页面的所有数据,而是其中某些重要信息,这就需要进行最重要的解析操作。
目前比较主流的解析方式有三种:
- xpath
- JsonPath
- BeautifulSoup
一、xpath
首先在chrome浏览器的扩展程序中下载安装Xpath Helper插件
之后在PyCharm pip install lxml库
xpath既可以解析本地文件,也可以解析服务器响应的数据
1. 解析本地文件:etree.parse()
以本地刚创建的一个html文件为例
运行下列代码,发现报错
from lxml import etree
tree = etree.parse('jiexi.html')
print(tree)
原因是lxml不允许html中的标签单个出现,即必须又开始标签,后面也要有关闭。
我们回去html中的第四行,添加一个’/'关闭即可
再次运行,打印成功
xpath基本语法:
- 路径查询
- 谓词查询
- 属性查询
- 模糊查询
- 内容查询
- 逻辑运算
1.路径查询
//:查找所有子孙节点,不考虑层级关系
/:找直接子节点
例如我们想要寻找ul下的li标签:
# 以下两行代码都可以
li_list = tree.xpath('//body/ul/li')
li_list = tree.xpath('//body//li')
注意:这里body前要用//,因为html的根节点是html,//放在最前面就是从根节点寻找所有的body标签。如果写成/,意思就变成了寻找body下的第一个子标签,是head而不是body,所以不会返回结果。
2.谓词查询
给li里加上属性id,如下图
利用li[@id]来查找id属性,/text()的作用是打印标签内容
# 查找所有有id的li标签
li_list = tree.xpath('//ul/li[@id]/text()')
输出结果: ['北京', '上海']
@id=[‘id名称’]来指定查找的id名称,记得要用引号括起来
# 找到id为l1的li标签
li_list = tree.xpath('//ul/li[@id="l1"]/text()')
输出结果: ['北京']
3.属性查询
查找某标签的属性值,利用/@class
# 查找到id为l1的li标签的class属性值
li = tree.xpath('//ul/li[@id="l1"]/@class')
输出结果: ['c1']
4.模糊查询
再添加两个id,查询包含某字符的标签
1.contains
# 查询id中包含‘l’的li标签
li = tree.xpath('//ul/li[contains(@id,"l")]/text()')
输出结果: ['北京', '上海']
2.starts-with
# 查询id的值以'l'开头的li标签
li = tree.xpath('//ul/li[starts-with(@id,"l")]/text()')
输出结果: ['北京', '上海']
5.内容查询
即/text()获取标签内容
6.逻辑运算
利用and匹配标签内容
利用‘|’表达或关系,但只能通过标签操作,不能通过属性操作
# 查询id为'l1'和class为'c1'的li标签
li = tree.xpath('//ul/li[@id="l1" and @class="c1"]/text()')
输出结果: ['北京']
# 查询id为'l1'或id为'l2'的li标签
li = tree.xpath('(//ul/li[@id="l1"] | //ul/li[@id="l2"])/text()')
输出结果: ['北京', '上海']
2. 解析服务器响应数据:etree.HTML
以获取百度搜索的“百度一下”四个字为例
在网页按住“CTRL+SHIFT+X”打开Chrome xpath插件,此插件左边的框输入xpath查询语句,用于验证是否是我们想要的内容,右边黑框是搜索结果。找到正确结果后把搜索语句复制到代码中即可。
完整代码如下,xpath返回的结果是一个列表,如果只想要获取里面‘百度一下’四个字,只需result[0]即可
import urllib.request
url = 'https://www.baidu.com'
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
"Chrome/98.0.4758.102 Safari/537.36 "
}
request = urllib.request.Request(url=url, headers=headers)
response = urllib.request.urlopen(request)
content = response.read().decode('utf-8')
# 解析网页源码 获取想要的数据 “百度一下”四个字
from lxml import etree
# 解析服务器响应的内容
tree = etree.HTML(content)
result = tree.xpath('//input[@id="su"]/@value')
print(result)
总结
- 解析本地文件:etree.parse();解析服务器响应内容:etree.HTML
- xpath基本语法以及chrome xpath插件的使用