XPath 使用路径表达式在 HTML或XML文档中选取节点或节点集,节点集是指多个节点的集合,节点或节点集是通过沿着文档节点层次路径来选取的。
1、路径表达式
XPath使用的路径表达式类似于文件系统的路径,符号“/”是路径节点间的分隔符,类似于文件系统的目录分隔符。
例如下面的HTML文档:
<html> <head> <title>我的第一个网页</title> </head> <body> <h1>这是第一个网页</h1> <hr> <p class=“c1”>这是一个段落</p> </boyd> </html>
要选取<h1>元素节点的文本内容,可以写如下的XPath路径表达式:
/html/body/h1/text()
text()是XPath函数,用于获取已选取节点的文本内容,XPath函数在后面的课程会详细介绍。
在Python执行XPath表达式,需要先安装lxml库,前面已经安装了lxml库。
案例代码如下:
#导入lxml库
from lxml import etree
#定义HTML文档
htmcontent="<html>\
<head>\
<title>我的第一个网页</title>\
</head>\
<body>\
<h1>这是第一个网页</h1>\
<hr>\
<p class=“c1”>这是一个段落</p>\
</boyd>\
</html>\
"
# 读取HTML文档内容,返回选择器
selector = etree.HTML(htmcontent)
# 执行xpath表达式
# 选取的节点集内容以列表方式返回
select = selector.xpath("/html/body/h1/text()")
print(select)HTML文档内容内置在代码内,更好的方法是将HTML文档内容保存到一个HTML文件,程序使用文件对象加载HTML文件。
案例代码执行后,输出结果如下:
['这是第一个网页']
2、 HTML案例文件
在后面的案例中使用下面给出的HTML内容,执行案例程序时,需要把下面的HTML内容保存到本地,文件名是sample.html,编码格式是utf-8。
<html> <head> <title>落花生与济南的冬天</title> </head> <body> <div id="id_title"> <a href="#article1" target="_self">落花生</a> <a href="#article2" target="_self">济南的冬天</a> </div> <a name="article1"></a> <h1>落花生</h1> <h5>许地山</h5> <hr> <p> 我们家的后园有半亩空地。母亲说:“让它荒着怪可惜的,你们那么爱吃花生,就开辟出来种花生吧。”我们姐弟几个都很高兴,买种,翻地,播种,浇水,没过几个月,居然收获了。 </p> <p> 母亲说:“今晚我们过一个收获节,请你们的父亲也来尝尝我们的新花生,好不好?”母亲把花生做成了好几样食品,还咐附就在后园的茅亭里过这个节。 </p> <a name="article2"></a> <h1>济南的冬天</h1> <h5>老舍</h5> <hr> <p style="font-weight:bolder"> 对于一个在北平住惯的人,像我,冬天要是不刮风,便觉得是奇迹;济南的冬天是没有风声的。对于一个刚由伦敦回来的人,像我,冬天要能看得见日光,便觉得是怪事;济南的冬天是响晴的。自然,在热带的地方,日光是永远那么毒,响亮的天气,反有点叫人害怕。可是,在北中国的冬天,而能有温晴的天气,济南真得算个宝地。 </p> 设若单单是有阳光,那也算不了出奇。请闭上眼睛想:一个老城,有山有水,全在天底下晒着阳光,暖和安适地睡着,只等春风来把它们唤醒,这是不是个理想的境界? <p> </div> </boyd> </html>
3、定位符号
定位符号给出了构成路径表达式的基本符号,这些基本符号、节点名称、谓语、运算符、轴、XPath函数构成了路径表达式。

案例1:选取所有div节点下的a节点
#导入lxml库
from lxml import etree
#HTML文件路径
filename = "d://sample.html"
try:
#使用r模式打开文件,编码方式为utf-8
fp = open(filename,"r",encoding='utf-8')
content = fp.read()
#关闭文件对象
fp.close()
# 读取HTML文档内容,返回选择器
selector = etree.HTML(content)
# 选取所有div节点下的a节点
select = selector.xpath("//div/a")
print(select)
except IOError:
print("文件打开失败,%s文件不存在" % filename)程序执行结果如下所示:
[<Element a at 0x1be58c5a5c0>, <Element a at 0x1be58c5a600>]
案例2:选取p节点的style属性
#导入lxml库
from lxml import etree
#HTML文件路径
filename = "d://sample.html"
try:
#使用r模式打开文件,编码方式为utf-8
fp = open(filename,"r",encoding='utf-8')
content = fp.read()
#关闭文件对象
fp.close()
# 读取HTML文档内容,返回选择器
selector = etree.HTML(content)
# 选取所有div节点下的a节点
select = selector.xpath("//p/@style")
print(select)
except IOError:
print("文件打开失败,%s文件不存在" % filename)程序执行结果如下所示:
['font-weight:bolder']
案例3:选取body节点下的a节点
#导入lxml库
from lxml import etree
#HTML文件路径
filename = "d://sample.html"
try:
#使用r模式打开文件,编码方式为utf-8
fp = open(filename,"r",encoding='utf-8')
content = fp.read()
#关闭文件对象
fp.close()
# 读取HTML文档内容,返回选择器
selector = etree.HTML(content)
# 选取所有div节点下的a节点
select = selector.xpath("/html/body/a")
print(select)
except IOError:
print("文件打开失败,%s文件不存在" % filename)程序执行结果如下所示:
[<Element a at 0x1ccd332a580>]
4、 谓词与运算符
谓词是一个XPath表达式,配合路径表达式附加节点集的筛选条件,谓词也称为过滤器。谓词由节点或节点属性的值、运算符或XPath函数(函数会在后面的课程讲解)构成,并放置在一个中括号内。谓词计算结果可返回节点集、字符串、逻辑值以及数字。
谓词用方括号将XPath表达式括起来,谓词一般放置在节点名称的后面。
下表列出了XPath表达式支持的运算符:

一个完整的案例代码:
#导入lxml库
from lxml import etree
#HTML文件路径
filename = "d://sample.html"
try:
#使用r模式打开文件,编码方式为utf-8
fp = open(filename,"r",encoding='utf-8')
content = fp.read()
#关闭文件对象
fp.close()
# 读取HTML文档内容,返回选择器
selector = etree.HTML(content)
# 选取所有div节点下的a节点属性
#href等于#article1或#article2的字符串
select = selector.xpath("//div/a[@href='#article1' or @href='#article2']/text()")
print(select)
except IOError:
print("文件打开失败,%s文件不存在" % filename)程序执行结果如下所示:
['落花生', '济南的冬天']