获取属性
“@”不仅可以实现通过属性匹配节点,还可以直接获取属性所对应的值。示例代码如下:
#_*_coding:utf-8_*_
# 作者 :liuxiaowei
# 创建时间 :2/4/22 2:48 PM
# 文件 :使用@获取属性对应值.py
# IDE :PyCharm
from lxml import etree # 导入etree子模块
# 定义html字符串
html_str = '''
<div class="video_scroll">
<li class="level" id="one">什么是Java</li>
</div>
'''
html = etree.HTML(html_str) # 解析html字符串
# 获取li节点中的class属性值
li_class = html.xpath('//div/li/@class')
# 获取li节点中的id属性值
li_id = html.xpath('//div/li/@id')
print('class属性值:',li_class)
print('id属性值:',li_id)
程序运行结果如下:
class属性值: ['level']
id属性值: ['one']
按序获取属性值
如果同时匹配了多个节点,但只需要其中的某一个节点时,可以使用指定索引的方式获取对应的节点内容,不过XPath中的索引是从1开始的,所以需要注意不要与Python中的列表索引混淆。示例代码如下:
#_*_coding:utf-8_*_
# 作者 :liuxiaowei
# 创建时间 :2/4/22 3:00 PM
# 文件 :使用索引按序获取属性对应的值.py
# IDE :PyCharm
from lxml import etree # 导入etree子模块
# 定义html字符串
html_str = '''
<div class="video_scroll">
<li> <a href="javascript:" οnclick="login(0)" title="Java API文档">Java API文档</a> </li>
<li> <a href="javascript:" οnclick="login(0)" title="JDK的下载">JDK的下载</a> </li>
<li> <a href="javascript:" οnclick="login(0)" title="JDK的安装">JDK的安装</a> </li>
<li> <a href="javascript:" οnclick="login(0)" title="配置JDK">配置JDK</a> </li>
</div>
'''
html = etree.HTML(html_str) # 解析html字符串
# 获取所有li/a节点中title属性值
li_all = html.xpath('//div/li/a/@title')
print('所有属性值:',li_all)
# 获取第1个li/a节点中title属性值
li_first = html.xpath('//div/li[1]/a/@title')
print('第一个属性值:',li_first)
# 获取第4个li/a节点中title属性值
li_four = html.xpath('//div/li[4]/a/@title')
print('第四个属性值:',li_four)
html = etree.HTML(html_str) # 解析html字符串
# 获取最后一个li/a节点中title属性值
li_last = html.xpath('//div/li[last()]/a/@title')
print('最后一个属性值:',li_last)
# 获取第1个li/a节点中title属性值
li = html.xpath('//div/li[position()=1]/a/@title')
print('第一个位置的属性值:',li)
# 获取倒数第二个li/a节点中title属性值
li = html.xpath('//div/li[last()-1]/a/@title')
print('倒数第二个位置的属性值:',li)
# 获取位置大于1的li/a节点中title属性值
li = html.xpath('//div/li[position()>1]/a/@title')
print('位置大于1的属性值:',li)
程序运行结果如下:
所有属性值: ['Java API文档', 'JDK的下载', 'JDK的安装', '配置JDK']
第一个属性值: ['Java API文档']
第四个属性值: ['配置JDK']
最后一个属性值: ['配置JDK']
第一个位置的属性值: ['Java API文档']
倒数第二个位置的属性值: ['JDK的安装']
位置大于1的属性值: ['JDK的下载', 'JDK的安装', '配置JDK']
使用节点轴获取节点内容
除了以上的匹配方式以外,XPath还提供了一些节点轴的匹配方法,例如,获取祖先节点、子孙节点、兄弟节点等,示例代码如下:
#_*_coding:utf-8_*_
# 作者 :liuxiaowei
# 创建时间 :2/4/22 3:18 PM
# 文件 :使用节点轴的方式获取节点内容.py
# IDE :PyCharm
from lxml import etree # 导入etree子模块
# 定义html字符串
html_str = '''
<div class="video_scroll">
<li><a href="javascript:" οnclick="login(0)" title="Java API文档">Java API文档</a></li>
<li><a href="javascript:" οnclick="login(0)" title="JDK的下载">JDK的下载</a></li>
<li> <a href="javascript:" οnclick="login(0)" title="JDK的安装">JDK的安装</a> </li>
</div>
'''
html = etree.HTML(html_str) # 解析html字符串
# 获取li[2]所有祖先节点
ancestors = html.xpath('//li[2]/ancestor::*')
print('li[2]所有祖先节点名称:',[i.tag for i in ancestors])
# 获取li[2]祖先节点位置为body
body = html.xpath('//li[2]/ancestor::body')
print('li[2]指定祖先节点名称:',[i.tag for i in body])
# 获取li[2]属性为class="video_scroll"的祖先节点
class_div = html.xpath('//li[2]/ancestor::*[@class="video_scroll"]')
print('li[2]class="video_scroll"的祖先节点名称:',[i.tag for i in class_div])
# 获取li[2]/a所有属性值
attributes = html.xpath('//li[2]/a/attribute::*')
print('li[2]/a的所有属性值:',attributes)
# 获取div所有子节点
div_child = html.xpath('//div/child::*')
print('div的所有子节点名称:',[i.tag for i in div_child])
# 获取body所有子孙节点
body_descendant = html.xpath('//body/descendant::*')
print('body的所有子孙节点名称:',[i.tag for i in body_descendant])
# 获取li[1]节点后的所有节点
li_following = html.xpath('//li[1]/following::*')
print('li[1]之后的所有节点名称:',[i.tag for i in li_following])
# 获取li[1]节点后的所有同级节点
li_sibling = html.xpath('//li[1]/following-sibling::*')
print('li[1]之后的所有同级节点名称:',[i.tag for i in li_sibling])
# 获取li[3]节点前的所有节点
li_preceding = html.xpath('//li[3]/preceding::*')
print('li[3]之前的所有节点名称:',[i.tag for i in li_preceding])
程序运行结果如下:
li[2]所有祖先节点名称: ['html', 'body', 'div']
li[2]指定祖先节点名称: ['body']
li[2]class="video_scroll"的祖先节点名称: ['div']
li[2]/a的所有属性值: ['javascript:', 'login(0)', 'JDK的下载']
div的所有子节点名称: ['li', 'li', 'li']
body的所有子孙节点名称: ['div', 'li', 'a', 'li', 'a', 'li', 'a']
li[1]之后的所有节点名称: ['li', 'a', 'li', 'a']
li[1]之后的所有同级节点名称: ['li', 'li']
li[3]之前的所有节点名称: ['li', 'a', 'li', 'a']
总 结