目录
XPath是什么呢?
XPath,全称XML Path Language,是一种在XML文档中查找信息的语言,它被设计用来在XML结构中导航,尽管它同样适用于HTML文档。XPath最初于1999年11月16日成为W3C标准,旨在支持XSLT、XPointer等技术,通过路径表达式来选取XML文档中的节点或节点集。
Xpath的核心功能与特点
- 路径表达式:XPath使用类似文件系统路径的表达式来定位文档中的元素和属性。例如,/root/child 会选取根节点下的直接子节点child。
- 选择节点:XPath能精确选择元素、属性、文本节点等,支持绝对路径(如 /element)和相对路径(如 ./element 或 element)。
- 条件筛选:通过谓词(方括号内的表达式),可以基于条件选择节点,如 //book[@author='J.K. Rowling'] 选取所有作者为J.K. Rowling的book节点。
- 节点轴:XPath提供节点轴(如child::, parent::, self::等),帮助在节点树中导航。
- 函数支持:XPath提供了丰富的函数库,用于字符串处理、数值计算、节点测试等,如count(), normalize-space(), contains()等。
- 表达式组合:可以使用逻辑运算符(如 and, or)和算术运算符来组合复杂的表达式。
XPath的应用
- 在Web自动化测试中的应用:XPath在Selenium等工具中广泛用于Web元素的定位,提供了一种灵活的定位策略,尤其是在页面结构复杂时。
- 在爬虫技术中的应用:XPath是数据提取的关键工具,通过解析HTML文档,精准提取所需信息。
XPath中的路径表达式与节点以及相关语法
XPath路径表达式是XPath语言的核心部分,用于在XML或HTML文档中定位特定的节点。
XPath中的节点
XPath中的节点是XML文档结构的基本单位,它们构成了XML文档的树状结构。以下是XPath中七种类型的节点及其简要说明:
-
元素节点(Element):XML文档中最重要的节点类型,代表XML结构中的标签,如<book>、<title>等。
-
属性节点(Attribute):附属于元素节点的,提供额外信息。例如,<title lang="en">中的lang="en"就是属性节点。
-
文本节点(Text):元素节点内部的文本内容,例如<title>Harry Potter</title>中的"Harry Potter"。
-
命名空间节点(Namespace):定义元素和属性的命名空间,虽然在日常XPath使用中较少直接操作。以下为使用XPath查询带有命名空间的元素的例子。
from lxml import etree # 定义命名空间 ns = {'n': 'http://www.example.com/ns'} # 加载 XML 字符串 xml_data = """ <root xmlns:n="http://www.example.com/ns"> <n:element>Content</n:element> </root> """ root = etree.fromstring(xml_data) # 使用 XPath 查询 elements = root.xpath('n:element', namespaces=ns) # 输出元素内容 for element in elements: print(element.text) #Content
-
处理指令节点(Processing Instruction):XML文档中用于指导处理程序的指令,如<?xml-stylesheet type="text/xsl" href="style.xsl"?>。
-
注释节点(Comment):XML文档中的注释部分,如<!-- 这是一个注释 -->。
-
文档(根)节点(Document Node 或 Root Node):整个XML文档的顶级节点,其他所有节点都是其子节点。
XPath中的其他节点术语
基本值(Atomic value)
基本值又称原子值,基本值是无父或无子的节点。
<?xml version="1.0" encoding="ISO-8859-1"?>
<bookstore>
<book>
<title lang="en">Harry Potter</title>
<author>J K. Rowling</author>
<year>2005</year>
<price>29.99</price>
</book>
</bookstore>
在这个XML文档中,以下是一些基本值节点的例子:
- "Harry Potter":这是<title>元素的文本内容。
- "J K. Rowling":这是<author>元素的文本内容。
- "en":这是<title>元素的lang属性的值。
- "2005":这是<year>元素的文本内容。
- "29.99":这是<price>元素的文本内容。
项目(Item)
项目是基本值或节点
节点间的关系
在XPath中,节点间的关系是理解和使用XPath表达式的关键。以下是一个基于XML文档的示例,来说明几种主要的节点关系:
<bookstore>
<book>
<title lang="en">Harry Potter</title>
<author>J K. Rowling</author>
<year>2005</year>
<price>29.99</price>
</book>
<book>
<title lang="en">Learning XPath</title>
<author>John Doe</author>
<year>2020</year>
<price>19.99</price>
</book>
</bookstore>
节点间关系的例子
-
父节点(Parent)
- 示例:<title>元素的父节点是<book>。
- XPath表达式:从<title>元素选择其父节点,可以表示为./parent::book。
-
子节点(Children)
- 示例:<book>元素有四个子节点:<title>、<author>、<year>和<price>。
- XPath表达式:从<bookstore>元素选择所有<book>的子节点,可以表示为/bookstore/book/*。
-
同胞(Sibling)
- 示例:在第一个<book>元素中,<title>、<author>、<year>和<price>都是同胞节点。
- XPath表达式:选择与特定<title>元素同级的所有<author>元素,可以表示为./following-sibling::author或./preceding-sibling::author,具体取决于上下文。
-
先辈(Ancestor)
- 示例:<title>元素的先辈包括直接父节点<book>和祖父节点<bookstore>。
- XPath表达式:从任意<title>元素选择其所有先辈,可以表示为ancestor::*。
-
后代(Descendant)
- 示例:<bookstore>元素的后代包括所有的<book>、<title>、<author>、<year>和<price>元素。
- XPath表达式:选择所有<bookstore>的后代<title>元素,可以表示为descendant::title。
XPath路径表达式的语法
我们依旧按照上图中的实例XML文件
选取节点
XPath 使用路径表达式在 XML 文档中选取节点。节点是通过沿着路径或者 step 来选取的。
表达式 | 描述 |
---|---|
nodename | 选取此节点的所有子节点。 |
/ | 从根节点选取(取子节点)。 |
// | 从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置(取子孙节点)。 |
. | 选取当前节点。 |
.. | 选取当前节点的父节点。 |
@ | 选取属性。 |
在下面的表格中,我们已列出了一些路径表达式以及表达式的结果:
路径表达式 | 结果 |
---|---|
bookstore | 选取所有名为 bookstore 的节点。 |
/bookstore | 选取根元素 bookstore。 注释:假如路径起始于正斜杠( / ),则此路径始终代表到某元素的绝对路径! |
bookstore/book | 选取属于 bookstore 的子元素的所有 book 元素。 |
//book | 选取所有 book 子元素,而不管它们在文档中的位置。 |
bookstore//book | 选择属于 bookstore 元素的后代的所有 book 元素,而不管它们位于 bookstore 之下的什么位置。 |
//@lang | 选取名为 lang 的所有属性。 |
谓语(Predicates)
谓语用来查找某个特定的节点或者包含某个指定的值的节点。
谓语被嵌在方括号中。
在下面的表格中,我们列出了带有谓语的一些路径表达式,以及表达式的结果:
路径表达式 | 结果 |
---|---|
/bookstore/book[1] | 选取属于 bookstore 子元素的第一个 book 元素。 |
/bookstore/book[last()] | 选取属于 bookstore 子元素的最后一个 book 元素。 |
/bookstore/book[last()-1] | 选取属于 bookstore 子元素的倒数第二个 book 元素。 |
/bookstore/book[position()<3] | 选取最前面的两个属于 bookstore 元素的子元素的 book 元素。 |
//title[@lang] | 选取所有拥有名为 lang 的属性的 title 元素。 |
//title[@lang='eng'] | 选取所有 title 元素,且这些元素拥有值为 eng 的 lang 属性。 |
/bookstore/book[year>2019] | 选取 bookstore 元素的所有 book 元素,且其中的 year 元素的值须大于 2019。 |
/bookstore/book[year>2019]//title | 选取 bookstore 元素中的 book 元素的所有 title 元素,且其中的 year 元素的值须大于 2019。 |
选取未知节点
XPath 通配符可用来选取未知的 XML 元素。
通配符 | 描述 |
---|---|
* | 匹配任何元素节点。 |
@* | 匹配任何属性节点。 |
node() | 匹配任何类型的节点。 |
在下面的表格中,我们列出了一些路径表达式,以及这些表达式的结果:
路径表达式 | 结果 |
---|---|
/bookstore/* | 选取 bookstore 元素的所有子元素。 |
//* | 选取文档中的所有元素。 |
//title[@*] | 选取所有带有属性的 title 元素。 |
/bookstore/node() | 选取两个<book>元素,但不会匹配到文本节点、注释或处理指令。 |
选取若干路径
通过在路径表达式中使用"|"运算符,您可以选取若干个路径。
在下面的表格中,我们列出了一些路径表达式,以及这些表达式的结果:
路径表达式 | 结果 |
---|---|
//book/title | //book/price | 选取 book 元素的所有 title 和 price 元素。 |
//title | //price | 选取文档中的所有 title 和 price 元素。 |
/bookstore/book/title | //price | 选取属于 bookstore 元素的 book 元素的所有 title 元素,以及文档中所有的 price 元素。 |
XPath中的轴(Axes)
轴可定义相对于当前节点的节点集。
轴名称 | 结果 |
---|---|
ancestor | 选取当前节点的所有先辈(父、祖父等)。 |
ancestor-or-self | 选取当前节点的所有先辈(父、祖父等)以及当前节点本身。 |
attribute | 选取当前节点的所有属性。 |
child | 选取当前节点的所有子元素。 |
descendant | 选取当前节点的所有后代元素(子、孙等)。 |
descendant-or-self | 选取当前节点的所有后代元素(子、孙等)以及当前节点本身。 |
following | 选取文档中当前节点的结束标签之后的所有节点。 |
following-sibling | 选取当前节点之后的所有兄弟节点 |
namespace | 选取当前节点的所有命名空间节点。 |
parent | 选取当前节点的父节点。 |
preceding | 选取文档中当前节点的开始标签之前的所有节点。 |
preceding-sibling | 选取当前节点之前的所有同级节点。 |
self | 选取当前节点。 |
轴的相关案例
<family>
<person name="Alice" relation="mother">
<person name="Bob" relation="father">
<person name="Charlie" relation="child"/>
<person name="Diana" relation="child"/>
</person>
</person>
</family>
-
child轴:选取当前节点的直接子节点。
- 示例:从<family>元素选择所有子节点。
- XPath表达式:/family/child::person。
-
parent轴:选取当前节点的父节点。
- 示例:从任意<person>元素选择其父节点。
- XPath表达式:./parent::family 或简写为 ../。
-
descendant轴:选取当前节点的所有后代节点,无论深度。
- 示例:从<family>元素选择所有孙辈(或更远的后代)。
- XPath表达式:/family/descendant::person[@relation='child']。
-
self轴:选取当前节点本身。
- 示例:这在实际应用中较少,但可以用来强调当前节点。
- XPath表达式:./self::node() 或简写为 .。
-
following-sibling轴:选取当前节点之后的同级节点。
- 示例:从<person>元素(假设是“Alice”)选择下一个兄弟节点。
- XPath表达式:./following-sibling::person。
-
ancestor轴:选取当前节点的所有祖先节点。
- 示例:从任意<person>元素选择其所有祖先直到<family>。
- XPath表达式:./ancestor::family。
-
attribute轴:选取当前节点的属性。
- 示例:从任意<person>元素选择其name属性。
- XPath表达式:@name 或 ./attribute::name。
-
preceding-sibling轴:选取当前节点之前的同级节点。
- 示例:从<person>元素(假设是“Alice”)选择下一个兄弟节点。
- XPath表达式:./preceding-sibling::person。
- preceding轴:选取当前节点之前的所有节点。
1.示例:从<person>元素(假设是“Diana”)选取当前节点之前的所有节点。
2.XPath表达式:./preceding::person。 - following轴:选取当前节点之后的所有节点。
1.示例:从<person>元素(假设是“Charlie”)选取当前节点之后的所有节点。
2.XPath表达式:./following::person。
XPath 运算符
XPath 提供了多种运算符,用于在表达式中执行逻辑运算、比较、算术运算等操作。
这些运算符使得 XPath 表达式可以执行更复杂的查询。
以下是常用的 XPath 运算符及其用法:
逻辑运算符
运算符 | 描述 | 示例 |
---|---|---|
or | 或 | price=9.80 or price=9.70 |
and | 与 | price>9.00 and price<9.90 |
not | 非运算符 | not(price>9.00) |
示例
逻辑与运算符 and
选择 category 属性值为 children 且 lang 属性值为 en 的所有 <book>
元素。
//book[@category="children" and @lang="en"]
逻辑或运算符 or
选择 category
属性值为 children
或 cooking
的所有 <book>
元素。
//book[@category="children" or @category="cooking"]
逻辑非运算符 not()
选择所有 category
属性值不为 children
的 <book>
元素。
//book[not(@category="children")]
比较运算符
运算符 | 描述 | 示例 |
---|---|---|
= | 相等 | price=9.80 |
!= | 不相等 | price!=9.80 |
< | 小于 | price<9.80 |
<= | 小于或等于 | price<=9.80 |
> | 大于 | price>9.80 |
>= | 大于或等于 | price>=9.80 |
示例
等于运算符 =
选择 category
属性值为 children
的所有 <book>
元素。
//book[@category='children']
不等于运算符 !=
选择所有 category
属性值不为 children
的 <book>
元素。
//book[@category!='children']
小于运算符 <
选择价格小于 30.00 的所有 <book>
元素
//book[price<30.00]
小于或等于运算符 <=
选择价格小于或等于 30.00 的所有 <book>
元素
//book[price<=30.00]
大于运算符 >
选择价格大于 30.00 的所有 <book>
元素。
//book[price>30.00]
大于或等于运算符 >=
选择价格大于等于 30.00 的所有 <book>
元素。
//book[price>=30.00]
算术运算符
运算符 | 描述 | 示例 |
---|---|---|
| | 计算两个节点集 | //book|//cd |
+ | 加法 | 6 + 4 |
- | 减法 | 6 - 4 |
* | 乘法 | 6 * 4 |
div | 除法 | 8 div 4 |
mod | 模数(除余数) | 5 mod 2 |
示例
加法运算符 +
选择出版年份加一等于 2006 的所有 <book>
元素。
//book[year+1=2006]
减法运算符 -
选择出版年份减一等于 2004 的所有 <book>
元素。
//book[year-1=2004]
乘法运算符 *
选择价格乘以二大于 50.00 的所有 <book>
元素。
//book[price*2>50.00]
除法运算符 div
选择价格除以二小于 20.00 的所有 <book>
元素。
//book[price div 2<20.00]
模数运算符 mod
选择出版年份为偶数的所有 <book>
元素。
//book[year mod 2=0]
运用XPath分析页面的示例
下面是一个使用XPath分析页面的示例,假设我们要从一个虚构的电商网站中提取商品名称和价格。我们将使用Python的lxml库来实现这一过程。
from lxml import etree
# 假设这是HTML页面的文本内容,实际应用中你可能需要从文件或网络请求中获取
html_content = '''
<!DOCTYPE html>
<html>
<head>
<title>产品列表</title>
</head>
<body>
<div class="products">
<div class="product">
<h3 class="product-name">产品A</h3>
<span class="product-price">$19.99</span>
</div>
<div class="product">
<h3 class="product-name">产品B</h3>
<span class="product-price">$29.99</span>
</div>
</div>
</body>
</html>
'''
# 使用lxml解析HTML
tree = etree.fromstring(html_content)
# XPath表达式用于提取产品名称
product_names = tree.xpath('//div[@class="product"]/h3[@class="product-name"]/text()')
# XPath表达式用于提取产品价格
product_prices = tree.xpath('//div[@class="product"]/span[@class="product-price"]/text()')
# 打印产品名称和价格
for name, price in zip(product_names, product_prices):
print(f"产品名称: {name.strip()}, 价格: {price.strip()}")
结语
XPath,网页数据的导航者,简洁的语法蕴含着强大的选择力量。从基础到进阶,每一步学习都是通往高效数据提取的阶梯。实践与理解并行,它已成为开发者不可或缺的工具。在数据洪流中,XPath犹如一盏明灯,指引我们精确获取所需,不断解锁互联网的深层价值。继续探索,让XPath助力你的每一次数据之旅。
标签:XPath,运算符,元素,更新,选取,解读,book,节点 From: https://blog.csdn.net/weixin_47734224/article/details/142522248