本篇博文是自己在学习崔庆才的《Python3网络爬虫开发实战教程》的学习笔记系列,如果你也要这套视频教程的话,关注我公众号【小众技术】,关注后回复【PYTHON】,无套路免费送你一个学习大礼包,包括爬虫视频和电子书~
------------------------------------------------------------------华丽分割线----------------------------------------------------------------------------------------------------
1.前言
在python网络爬虫开发实践中,请求网页是基础,我们常用的请求工具是requests。而解析网页则是关键,我们常用的工具有两个,一个是正则表达式,另一个是Python库。但正则表达式写起来很复杂,一不小心就会出错,所以如果你没有达到炉火纯青的地步就不推荐使用了。
我们常用的是python库里面的Xpath,这是一种很专业的在XML中查找信息的语言,但由于它提供了一种非常简洁明了的路径表达式,所以同样也可以使用在HTML网页的解析中。今天刚好把Xpath的一些常用功能学完,趁热,赶紧写篇总结。
2.使用步骤
- 导入相关库:from lxml import etree
- 获取请求的网页代码,需为string形式
- 用Xpath解析规则解析节点信息
3.网页代码获取
要想解析网页,首先需要获取到网页代码,而可供Xpath解析的HTML形式有两种:一种是字符串形式的HTML代码,一种是装有代码的html文件。
from lxml import etree
import requests,pprint
text = '''
<div>
<ul>
<li class="item-0"><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></li>
</ul>
</div>
'''
#1.直接解析字符串,使之变成xpath能看懂的格式
html = etree.HTML(text)
#2.解析HTML文件
html = etree.parse('./text.html',etree.HTMLParser())
result = html.xpath('//li/a/text()')
print(result)
结果都是
['first item', 'second item', 'third item', 'fourth item', 'fifth item']
4.xpath解析规则
表达式 | 描述 |
---|---|
// | 选取子孙节点 |
/ | 选取直接子节点 |
. | 选取当前节点 |
.. | 选取当前节点直接父节点 |
@ | 选取属性 |
text() | 选取节点文本值 |
[contains(@属性,'其中一个值')] | 属性多值匹配时使用 |
/ancestor::*/节点名 | 选取全部祖先解点/某一全部祖先节点 |
/attribute::*/属性名 | 选取节点全部属性/某一属性 |
/child:: | 选取所有直接子节点 |
/following::* | 获取当前节点之后的所有节点 |
/following-sibling::* | 获取所有同级节点 |
|
各种情况,逐一分析
from lxml import etree
import requests,pprint
text = '''
<div>
<ul>
<li class="item-1 th" id='asd'><a href="link1.html">first item</a></li>
<li class="item-2"><a href="link2.html">second item</a></li>
<li class="item-3"><a href="link3.html">third item</a></li>
<li class="item-4"><a href="link4.html">fourth item</a></li>
<li class="item-5"><a href="link5.html">fifth item</a></li>
</ul>
</div>
'''
html = etree.HTML(text)
#基础表达式
#1.筛选全部的li节点,输出5个结果
html.xpath('//li')
#2.筛选全部节点,输出14个结果
html.xpath('//*')
#3.筛选ul节点的全部直接子节点(只包括li,不包括li中的a),共5个结果
html.xpath('//ul/*')
#4.筛选ul节点的全部子孙节点(包括li,也包括li中的a),共10个结果
html.xpath('//ul//*')
#5.筛选ul节点的直接父节点,输出节点div
html.xpath('//ul/..')
#按节点轴进行筛选
#6.输出ul节点的全部祖先节点,输出div,body,html
html.xpath('//ul/ancestor::*')
#7.输出第一个li元素所有属性值,class的值item-0,和id的值asd
html.xpath('//li[1]/attribute::*')
#8.输出第一个li节点后的所有节点,输出8个节点,包括li和a
html.xpath('//li[1]/following::*')
#9.输出第一个节点的同级节点,输出4个节点
html.xpath('//li[1]/following-sibling::*')
#输出属性值或文本值
#10.输出所有a节点的值,输出['first item', 'second item', 'third item', 'fourth item', 'fifth item']
html.xpath('//a/text()')
#11.输出所有li节点的class属性值,结果为['item-1', 'item-2', 'item-3', 'item-4', 'item-5']
html.xpath('//li/@class')
#按属性值选择节点
#12.筛选class值为item-2的li,输出一个结果
html.xpath('//li[@class = "item-2"]')
#13.筛选class值为th的li,因为要选取的class有多个属性值,所以需要用到contains函数,单一值也可用contains
html.xpath('//li[contains(@class,"th")]')
#14.选取class为th和item-2的li节点
html.xpath('//li[contains(@class,"th") or @class="item-2"]')
#按顺序选择节点
#15.选取最后一个li节点中a的文本值,输出fifth item
html.xpath('//li[last()]/a/text()')
#16.选取序号小于3的li节点,输出前两个li
html.xpath('//li[position()<3]')
#17.选取倒数第三个节点
html.xpath('//li[last()-2]')
5.注意事项
如果掌握了以上几种筛选的方式,那么解析HTML你将易如反掌,但同时有几个使用xpath要注意的地方:
1.当你筛选了多个数据的时候,Xpath返回的是一个列表
2.Xpath是以节点为筛选对象进行网页解析