版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/chengqiuming/article/details/86373220
一 子节点
1 点睛
我们通过/或//即可查找元素的子节点或子孙节点。
2 实战1——获取子节点
2.1 代码
from lxml import etree
html = etree.parse('./test.html', etree.HTMLParser())
# 选择li节点的所有直接a子节点
# 这里通过追加/a即选择了所有li节点的所有直接a子节点。
# 因为//li用于选中所有li节点,/a用于选中li节点的所有直接子节点a,二者组合在一起即获取所有li节点的所有直接a子节点。
result = html.xpath('//li/a')
print(result)
2.2 结果
E:\WebSpider\venv\Scripts\python.exe E:/WebSpider/4_1.py
[<Element a at 0x2138f113408>, <Element a at 0x2138f113448>, <Element a at 0x2138f113488>, <Element a at 0x2138f1134c8>, <Element a at 0x2138f113508>]
3 实战2——获取子孙节点
3.1 代码
from lxml import etree
html = etree.parse('./test.html', etree.HTMLParser())
# 要获取ul节点下的所有子孙a节点
result = html.xpath('//ul//a')
print(result)
3.2 结果
E:\WebSpider\venv\Scripts\python.exe E:/WebSpider/4_1.py
[<Element a at 0x2ad495c3408>, <Element a at 0x2ad495c3448>, <Element a at 0x2ad495c3488>, <Element a at 0x2ad495c34c8>, <Element a at 0x2ad495c3508>]
3.3 说明
这里我们要注意/和//的区别,其中/用于获取直接子节点,//用于获取子孙节点。
二 父节点
1 实战1
1.1 代码
from lxml import etree
html = etree.parse('./test.html', etree.HTMLParser())
# 现在首先选中href属性为link4.html的a节点,然后再通过..获取其父节点,
# 然后再获取其class属性,相关代码如下:
result = html.xpath('//a[@href="link4.html"]/../@class')
print(result)
1.2 结果
E:\WebSpider\venv\Scripts\python.exe E:/WebSpider/4_1.py
['item-1']
1.3 说明
检查一下结果发现,这正是我们获取的目标li节点的class。
2 实战2
2.1 代码
from lxml import etree
html = etree.parse('./test.html', etree.HTMLParser())
# 通过parent::来获取父节点
result = html.xpath('//a[@href="link4.html"]/parent::*/@class')
print(result)
2.2 结果
E:\WebSpider\venv\Scripts\python.exe E:/WebSpider/4_1.py
['item-1']
三 属性匹配
1 代码
from lxml import etree
html = etree.parse('./test.html', etree.HTMLParser())
# @符号进行属性过滤
# 选取class为item-1的li节点
# 这里我们通过加入[@class="item-0"],限制了节点的class属性为item-0,
# 而HTML文本中符合条件的li节点有两个,所以结果应该返回两个匹配到的元素。
result = html.xpath('//li[@class="item-0"]')
print(result)
2 结果
E:\WebSpider\venv\Scripts\python.exe E:/WebSpider/4_1.py
[<Element li at 0x1e9db193408>, <Element li at 0x1e9db193448>]
3 说明
匹配结果正是两个。
四 文本获取
1 实战
1.1 文件
<div>
<ul>
<li class="item-0"><a href="link1.html">first item</a>OK</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>
1.2 代码
from lxml import etree
html = etree.parse('./test.html', etree.HTMLParser())
# 这里获取的是li的文本,而不是a的文本
result = html.xpath('//li[@class="item-0"]/text()')
print(result)
1.3 结果
E:\WebSpider\venv\Scripts\python.exe E:/WebSpider/4_1.py
['OK', '\r\n ']
1.4 说明
OK对应的是第1个li的文本。
\r\n 对应的是第5个li的文本,因为parse会补齐li的尾标签,但尾标签会换行。
2 实战2——获取li中a标签的文本
2.1 点睛
是先选取a节点再获取a节点的文本
2.2 代码
from lxml import etree
html = etree.parse('./test.html', etree.HTMLParser())
result = html.xpath('//li[@class="item-0"]/a/text()')
print(result)
2.3 结果
E:\WebSpider\venv\Scripts\python.exe E:/WebSpider/4_1.py
['first item', 'fifth item']
2.4 说明
内容都是属性为item-0的li节点的文本。
3 实战3
3.1 点睛
使用//
3.2 代码
from lxml import etree
html = etree.parse('./test.html', etree.HTMLParser())
result = html.xpath('//li[@class="item-0"]//text()')
print(result)
3.3 结果
E:\WebSpider\venv\Scripts\python.exe E:/WebSpider/4_1.py
['first item', 'OK', 'fifth item', '\r\n ']
3.4 说明
这里的返回结果是4个。可想而知,这里是选取所有子孙节点的文本,其中两个就是li的子节点a节点内部的文本,另外2个就是两个li节点内部的文本,即OK和换行符。
所以说,如果要想获取子孙节点内部的所有文本,可以直接用//加text()的方式,这样可以保证获取到最全面的文本信息,但是可能会夹杂一些换行符等特殊字符。如果想获取某些特定子孙节点下的所有文本,可以先选取到特定的子孙节点,然后再调用text()方法获取其内部文本,这样可以保证获取的结果是整洁的。