XPath 选取节点时使用的表达式是一种路径表达式。节点是通过路径(path)或者步(steps)来选取的。

本章使用以下 XML 文档作为示例。

<?xml version="1.0" encoding="utf8"?>
<bookstore>
<book>
<title lang="eng">Harry Potter</title>
<price>29.99</price>
</book>
<book>
<title lang="eng">Learning XML</title>
<price>39.95</price>
</book>
</bookstore>

选取节点

以下为基本路径的表达方式,记住 XPath 的路径表达式都是基于某个节点之上的,例如最初的当前节点一般是根节点,这与 Linux 下路径切换原理是一样的。

表达式 描述
nodename 选取已匹配节点下名为 nodename 的子元素节点。
/ 如果以 / 开头,表示从根节点作为选取起点。
// 在已匹配节点后代中选取节点,不考虑目标节点的位置。
. 选取当前节点。
.. 选取当前节点的父元素节点。
@ 选取属性。
>>> from lxml import etree
>>> xml = """<?xml version="1.0" encoding="utf8"?>
<bookstore>
<book>
<title lang="eng">Harry Potter</title>
<price>29.99</price>
</book>
<book>
<title lang="eng">Learning XML</title>
<price>39.95</price>
</book>
</bookstore>""" # 得到根节点
>>> root = etree.fromstring(xml)  
>>> print root
<Element bookstore at 0x2c9cc88> # 选取所有book子元素
>>> root.xpath('book')  
[<Element book at 0x2d88878>, <Element book at 0x2d888c8>] # 选取根节点bookstore
>>> root.xpath('/bookstore')  
[<Element bookstore at 0x2c9cc88>] # 选取所有book子元素的title子元素
>>> root.xpath('book/title')  
[<Element title at 0x2d88878>, <Element title at 0x2d888c8>] # 以根节点为始祖,选取其后代中的title元素
>>> root.xpath('//title')    
[<Element title at 0x2d88878>, <Element title at 0x2d888c8>] # 以book子元素为始祖,选取后代中的price元素
>>> root.xpath('book//price')  
[<Element price at 0x2ca20a8>, <Element price at 0x2d88738>] # 以根节点为始祖,选取其后代中的lang属性值
>>> root.xpath('//@lang')    
['eng', 'eng']

预判(Predicates)

预判是用来查找某个特定的节点或者符合某种条件的节点,预判表达式位于方括号中。

# 选取bookstore的第一个book子元素
>>> root.xpath('/bookstore/book[1]')          
[<Element book at 0x2ca20a8>] # 选取bookstore的最后一个book子元素
>>> root.xpath('/bookstore/book[last()]')        
[<Element book at 0x2d88878>] # 选取bookstore的倒数第二个book子元素
>>> root.xpath('/bookstore/book[last()-1]')      
[<Element book at 0x2ca20a8>] # 选取bookstore的前两个book子元素
>>> root.xpath('/bookstore/book[position()<3]')    
[<Element book at 0x2ca20a8>, <Element book at 0x2d88878>] # 以根节点为始祖,选取其后代中含有lang属性的title元素
>>> root.xpath('//title[@lang]')     
[<Element title at 0x2d888c8>, <Element title at 0x2d88738>] # 以根节点为始祖,选取其后代中含有lang属性并且值为eng的title元素
>>> root.xpath("//title[@lang='eng']")
[<Element title at 0x2d888c8>, <Element title at 0x2d88738>] # 选取bookstore子元素book,条件是book的price子元素要大于35
>>> root.xpath("/bookstore/book[price>35.00]")
[<Element book at 0x2ca20a8>] # 选取bookstore子元素book的子元素title,条件是book的price子元素要大于35
>>> root.xpath("/bookstore/book[price>35.00]/title")
[<Element title at 0x2d888c8>]

通配符

通配符 描述
*  匹配任何元素。
@* 匹配任何属性。
node() 匹配任何类型的节点。
# 选取 bookstore 所有子元素
>>> root.xpath('/bookstore/*')
[<Element book at 0x2d888c8>, <Element book at 0x2ca20a8>] # 选取根节点的所有后代元素
>>> root.xpath('//*')  
[<Element bookstore at 0x2c9cc88>, <Element book at 0x2d888c8>, <Element title at 0x2d88738>, <Element price at 0x2d88878>, <Element book at 0x2ca20a8>, <Element title at 0x2d88940>, <Element price at 0x2d88a08>] # 选取根节点的所有具有属性节点的title元素
>>> root.xpath('//title[@*]')  
[<Element title at 0x2d88738>, <Element title at 0x2d88940>] # 选取当前节点下所有节点。'\n ' 是文本节点。
>>> root.xpath('node()')
['\n ', <Element book at 0x2d888c8>, '\n ', <Element book at 0x2d88878>, '\n'] # 选取根节点所有后代节点,包括元素、属性、文本。
>>> root.xpath('//node()')
[<Element bookstore at 0x2c9cc88>, '\n ', <Element book at 0x2d888c8>, '\n ', <Element title at 0x2d88738>, 'Harry Potter', '\n ', <Element price at 0x2d88940>, '29.99', '\n ', '\n ', <Element book at 0x2d88878>, '\n ', <Element title at 0x2ca20a8>, 'Learning XML', '\n ', <Element price at 0x2d88a08>, '39.95', '\n ', '\n']

或条件选取

使用 "|" 运算符,你可以选取符合“或”条件的若干路径。

# 选取所有book的title元素或者price元素
>>> root.xpath('//book/title|//book/price')  
[<Element title at 0x2d88738>, <Element price at 0x2d88940>, <Element title at 0x2ca20a8>, <Element price at 0x2d88a08>] # 选择所有title或者price元素
>>> root.xpath('//title|//price')  
[<Element title at 0x2d88738>, <Element price at 0x2d88940>, <Element title at 0x2ca20a8>, <Element price at 0x2d88a08>] # 选择book子元素title或者全部的price元素
>>> root.xpath('/bookstore/book/title|//price')
[<Element title at 0x2d88738>, <Element price at 0x2d88940>, <Element title at 0x2ca20a8>, <Element price at 0x2d88a08>]

[XPath] XPath 与 lxml (二)XPath 语法的更多相关文章

  1. xpath教程 2 - lxml库

    xpath教程 2 - lxml库 这些就是XPath的语法内容,在运用到Python抓取时要先转换为xml. lxml库 lxml 是 一个HTML/XML的解析器,主要的功能是如何解析和提取 HT ...

  2. Python爬虫 XPath语法和lxml模块

    XPath语法和lxml模块 什么是XPath? xpath(XML Path Language)是一门在XML和HTML文档中查找信息的语言,可用来在XML和HTML文档中对元素和属性进行遍历. X ...

  3. XPath语法和lxml模块

    XPath语法和lxml模块 什么是XPath? xpath(XML Path Language)是一门在XML和HTML文档中查找信息的语言,可用来在XML和HTML文档中对元素和属性进行遍历. X ...

  4. Python爬虫11-XML与XPath概述及lxml库的应用

    GitHub代码练习地址:用lxml解析HTML,文件读取,etree和XPath的配合使用:https://github.com/Neo-ML/PythonPractice/blob/master/ ...

  5. JAVA与DOM解析器提高(DOM/SAX/JDOM/DOM4j/XPath) 学习笔记二

    要求 必备知识 JAVA基础知识.XML基础知识. 开发环境 MyEclipse10 资料下载 源码下载   sax.dom是两种对xml文档进行解析的方法(没有具体实现,只是接口),所以只有它们是无 ...

  6. 爬虫之lxml - etree - xpath的使用

    # 解析原理: # - 获取页面源码数据 # - 实例化一个etree对象,并且将页面源码数据加载到该对象中 # - 调用该对象的xpath方法进行指定标签定位 # - xpath函数必须结合着xpa ...

  7. xpath教程 1 - 什么是XPath

    xpath教程 1 什么是XPath? XPath (XML Path Language) 是一门在 XML 文档中查找信息的语言,可用来在 XML 文档中对元素和属性进行遍历. W3School官方 ...

  8. xpath如何使用正则、xpath定位svg标签、xpath常用集合

    自己用到的xpath都收集下咯!!! 持续更新本页面 xpath查找svg图标 xpath('//*[local-name() = "svg" and @class="_ ...

  9. Azure Terraform(二)语法详解

    一,引言 上篇文章开始,我们简单介绍了以下通过基础设施管理工具----- Terraform,通过它来统一管理复杂的云基础设施资源.作为入门演示,使用Terraform 部署Azure 资源组的方式直 ...

  10. Azure Bicep(二)语法简介

    一,引言 上一篇文章有介绍到 Azure Bicep 的部署问题,文中也只是演示部署范围为 Sub,并将演示的 Azure Resource Group 到 Azure.给定 Bicep 文件,可以部 ...

随机推荐

  1. 8个日志级别(OFF、FATAL、ERROR、WARN、INFO、DEBUG、TRACE、 ALL)

    log4j定义了8个级别的log(除去OFF和ALL,可以说分为6个级别),优先级从高到低依次为:OFF.FATAL.ERROR.WARN.INFO.DEBUG.TRACE. ALL. ALL 最低等 ...

  2. (笔记)Linux下的准确延时,#include <linux/delay.h>调用出错

    在编写应用层程序时,有时需要延时一下,这个时候该怎么办呢? 在内核代码中,我们经常会看到这样的头文件使用#include <linux/delay.h>,心想着直接调用这个就可以了吧!可是 ...

  3. 关于eclipse导工程或移植工程常碰到的错误汇总

      在开发过程中,eclipse是使用得最多的IDE,但由于其开源且免费的性质决定了其不然有很多的BUG,在项目很赶的时期碰到某些很恶的错误很浪费时间,也很让人郁闷,现我总结一下我碰到的错误并总结下对 ...

  4. Java如何检查一个线程停止或没有?

    Java如何检查一个线程停止或没有? 解决方法 下面的示例演示如何使用 isAlive()方法检查一个线程是否停止. public class Main { public static void ma ...

  5. LintCode #2 尾部的零

    计算阶乘尾部的0的个数,初一看很简单. 先上代码 public static long GetFactorial(long n) { || n == ) ; ); } //Main方法中调用 ); ; ...

  6. jQuery table td可编辑

    参考链接: http://www.freejs.net/ http://www.freejs.net/article_biaodan_34.html http://www.freejs.net/sea ...

  7. (实用)将wordpad添加到Windows PowerShell中

    PowerShell能够直接打开notepad,但是无法调用wordpad,因为后者的可执行文件并不在系统默认的环境变量$env:Path中,只要将wordpad所在的路径添加到$env:Path,就 ...

  8. 某软件大赛C#版考题整理——【单选题】

    多选题:http://www.cnblogs.com/zxlovenet/p/3525849.html 编程题:http://www.cnblogs.com/zxlovenet/p/3525854.h ...

  9. windows server 安装phpVirtualBox web服务

    这是我在Windows server 2012 下的安装过程 (1) 安装virtualbox (2) 安装IIS和PHP, 参考: https://msdn.microsoft.com/zh-cn/ ...

  10. Linux下seq的使用

    seq - print a sequence of numbers [root@gechong ~]# man seq 主要有一下三个参数 -f:用来格式化输出 -s:用来指定分隔符号,默认是回车 - ...