XPath 是一门在 XML 文档中查找信息的语言。XPath 可用来在 XML 文档中对元素和属性进行遍历,而将 HTML文档转换成 XML文档后,就可以用 XPath 查找 HTML 节点或元素。
XML 文档的特点:
XML 文档中的每个成分都是一个节点。整个文档是一个根节点;每个 XML 标签是一个元素节点;包含在 XML 元素中的文本是文本节点;每一个 XML 属性是一个属性节点;注释则属于注释节点。
其中,元素节点可以包含任意的元素节点、文本节点或属性节点,而文本节点或属性节点则不能包含节点。
XPath语法的特点:
XPath 使用路径表达式在 XML 文档中进行导航
XPath 包含一个标准函数库
XPath 表达式可返回节点集、字符串、逻辑值以及数字。
常用的XPath 开发工具:
1.开源的XPath表达式编辑工具:XMLQuire(仅XML格式文件可用)。
2.Firefox插件 Try XPath。
3.Chrome插件 XPath Helper。推荐!可以直接在网页上使用xpath定位元素,非常方便。(安装详情见参考文献2)
一、XPath语法介绍
1. 选取节点
下表列出了常用的路径表达式:
表达式
描述
nodename
选取此节点的所有子节点
/
如果在路径最前面代表从根节点选取,否则表示选择某节点的子节点
//
从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置
.
表示当前节点
..
表示当前节点的父节点
@href
节点href属性的值(/@href:当前节点href属性的值;//@href:当前节点和子孙节点href属性的值)
text()
节点的文本内容(/text():当前节点的文本内容;//text():当前节点和子孙节点的文本内容)
2.谓语
谓语:用来查找某个特定的节点或者包含某个指定属性值的节点,被嵌在方括号中。
/bookstore/book[1]:选取属于 bookstore 子元素的第一个 book 元素。注意位置顺序是从1开始的,和python不一样!
/bookstore/book[last()]:选取属于 bookstore 子元素的最后一个 book 元素。
/bookstore/book[last()-1]:选取属于 bookstore 子元素的倒数第二个 book 元素。
/bookstore/book[position()<3]:选取最前面的两个属于 bookstore 元素的子元素的 book 元素。
//title[@lang]:选取拥有 lang 属性的 title 元素。
//title[@lang=’eng’]:选取 lang属性值为’eng’的 title 元素。
/bookstore/book[@price>35.00]:选取 bookstore子元素中满足条件的book 元素,条件:price属性的值须大于 35.00。
3.XPath的运算符
加法:+
减法:-
乘法:*
除法:div
=:等于
!=:不等于
<:小于
<=:小于或等于
>:大于
>:大于或等于
or:或
and:与
mod:计算除法的余数
4.XPath的轴
轴可定义相对于当前节点的节点集。
语法:轴名称::节点[谓语]
常用的轴:
ancestor:选取当前节点的所有先辈节点(父、祖父等)。
ancestor-or-self:选取当前节点的所有先辈节点(父、祖父等)以及当前节点本身。
attribute:选取当前节点的所有属性。
self:选取当前节点。
child:选取当前节点的所有子节点。
parent:选取当前节点的父节点。
descendant:选取当前节点的所有后代节点(子、孙等)。
descendant-or-self:选取当前节点的所有后代节点(子、孙等)以及当前节点本身。
示例:
//li[@data=”one”]/ancestor::div:选取属性data=”one”的li节点的所有div祖先节点。
//li[@data=”one”]/ancestor::*:选取属性data=”one”的li标签的所有祖先节点。
//div[@id=”testid”]/attribute::*:选取id=”testid”的div节点的所有属性值。
//div[@id]/self::div[@data-h]/attribute::*:选取含id属性和data-h属性的div标签的所有属性值
//div[@id=”testid”]/child::*:选取id=”testid”的div节点的所有子节点。
//li[@data=”one”]/parent::ol/li[last()]/text():选取属性data=”one”的li节点的父节点ol,其最后一个li子节点的文本值。
注意:由于每个元素节点只有唯一的一个父节点,所以“parent::父节点”等价于“parent::*” 。
5.XPath常用函数
contains ()函数:
//div[ contains(@class, ‘in’) ]:选择class属性值中包含有’in’字符串的div节点。
text()函数:节点的文本值
//a[text()=’baidu’]:选取文本值等于’baidu’的a节点。
//a/text():获取a节点文本内容。
last()函数:
/bookstore/book[last()]:选取属于 bookstore 子节点的最后一个 book 节点。
position()函数:返回节点的索引位置(从1开始)
/bookstore/book[position()<=3]:选取属于 bookstore 子节点的前三个 book 节点。
starts-with()函数:
//div[starts-with(@class,’in’)]:选择class属性值以字符串’in’开头的div节点。
ends-with()函数:
//div[ends-with(@class,’in’)]:选择class属性值以字符串’in’结尾的div节点。
not()函数:表示否定
//input[@name=‘identity’ and not( contains(@class,‘a’) )]:
选择属性name=‘identity’ 并且 class属性值中不包含字符’a’的input节点。
not()函数通常与返回值为true or false的函数组合起来用,比如contains(),starts-with()等。但有一种特别情况需注意一下://input[@id]:匹配出含有id属性的input节点;//input[not(@id)]:匹配出不含有id属性的input节点。
6.其他
1.通配符
使用通配符“*”可用来选取未知的 XML 元素。
*:匹配任何元素节点。
@*:匹配任何属性节点。
node():匹配任意类型的节点(元素、属性、文本、注释以及根节点)。
2.选取多条路径
通过在路径表达式中使用“|”运算符,可以选取多条路径。
//book/title | //book/price:选取 book 元素的所有 title 和 price 元素。
//title | //price:选取文档中的所有 title 和 price 元素。
二、xpath在python中的具体运用
lxml库是一个XML、HTML的解析器,主要用于解析和提取XML、HTML数据。lxml库先将HTML文档解析,然后就可以使用XPath 搜索或遍历HTML文档中的节点。
使用lxml解析HTML数据的两种方式:
1.解析HTML字符串:
from lxml import etree
# HTML字符串
text = ”’
Harry Potter
J K. Rowling
杰克罗琳
2005
29.99
”’
# 使用HTML()方法解析字符串
# HTML()默认使用的就是HTML解析器,如果遇到不规范的HTML代码,会自动补全。
html_element = etree.HTML(text)
# 解析后就可以调用xpath方法了
name = html_element.xpath(‘//book/name/text()’)
print(name)
# 返回值:
# [‘杰克罗琳’]
2.直接解析HTML文件:
from lxml import etree
# 创建HTML解析器,指定解析器使用的编码格式(需要和文件编码格式一致)
parser = etree.HTMLParser(encoding=’utf-8′)
# parse()默认的是XML解析器,在解析HTML代码时,如果HTML代码不规范,则会报错!
# 因此需要指定解析器为HTML解析器,这样不规范的HTML代码,会自动补全!
html_element = etree.parse(‘./test.html’, parser=parser)
#解析后就可以调用xpath方法了
name = html_element.xpath(‘//book/name/text()’)
print(name)
# 返回值:
# [‘杰克罗琳’]
注意:
1.xpath返回的永远是列表,即使没有匹配到任何元素也返回的是空列表。
2.根节点和任意元素节点都可以使用xpath方法去搜索、遍历其子节点。
# tostring()方法可以将节点对象转换成字节,解码后就可以查看节点内容
author_ele = html_element.xpath(‘//book/author’)[0]
result = etree.tostring(author_ele, encoding=’utf-8′).decode(‘utf-8’)
print(result)
# 返回值:
# J K. Rowling
参考文献: