当前位置: 首页 > news >正文

网络爬虫中Xpath的使用方法

正则表达式虽然可以处理包含了诸如 HTML 或 XML 内容的字符串,但只能根据文本的
特征匹配字符串,而忽略字符串所包含的内容的真实格式。为了解决这个问题,Python 引入
XPath 以及支持 XPath 的第三方库 lxml,专门对 XML 或 HTML 格式的数据进行解析。接下来,
本节将针对 XPath 和 lxml 的相关内容进行详细介绍。

一、XPath 简介

XPath 即 XML 路径查询语言(XML Path Language),是一种用于确定 XML 文档中部分
节点位置的语言。它起初只支持搜索 XML 文档,更新后能支持搜索 HTML 文档。截至完稿
时,XPath 的最新版本为 XPath3.1。
那么 XPath 是如何搜索 XML 或 HTML 文档呢?其实 XPath 基于 XML 或 HTML 的节点
树,沿着节点树的节点关系定位到目标节点所在的位置,并选取节点或节点集。为了形象地
描述出搜索节点的路径,XPath 提供了简洁明了的路径表达式,通过路径表达式可以快速地定
位与选取 XML 或 HTML 文档中的一个节点或者一组节点集。
与正则表达式相比,路径表达式的搜索方式大不相同。在这里,我们借用一个形象的例
子进行比较。假如我们把选取目标节点比作找金燕龙办公楼。如果我们通过正则表达式查找,
则正则表达式会告诉我们办公楼有哪些特征,办公楼的左边有哪些建筑、右边有哪些建筑。
这样的描述限定的查找范围比较宽泛,查找起来比较烦琐。如果我们通过路径表达式查找,
则路径表达式会直接告诉我们办公楼的具体位置,即中国北京市昌平区建材城西路金燕龙办
公楼。这样的描述更加精准、更易查找。
路径表达式描述了从一个节点到另一个节点或一组节点的路径。这些路径与在常规的计算
机文件系统中见到的路径非常相似。例如,“/学生名单/班级/学生/籍贯”就是一个路径表达式,
该路径表达式也是用“/”字符进行分隔的,只不过它分隔的是节点,而不是目录。接下来,通
过一张示意图来描述 XML 文档、XML 节点树与路径表达式的关系,具体如图 4-1 所示。
422ec9dbdf0e41b0bf9788283e37e4ec.png
在图 4-1 中,从左到右、从上到下依次为 XML 文档、XML 节点树和路径表达式。其中,
路径表达式为“/bookstore/book/price”,它对应的路径为 XML 节点树中加粗的线条,用于选
取节点<price>对应的文本 39.95。

二、XPath 语法

我们如果要编写一个路径表达式,则要先了解 XPath 的语法,如此才能使用路径表达式
正确地选取节点。路径表达式会从某个节点开始沿着节点树查找节点,直至找到目标节点。
由于节点的多样性,为了帮助开发人员快速选取目标节点,XPath 提供了一套语法规则。下面
从选取节点、谓语、选取未知节点、选取若干路径这 4 个方面介绍 XPath 的语法。

1.选取节点

选取节点是最基础的操作之一。节点所在的路径既可以从根节点开始,也可以从任意位
置开始。选取节点的表达式如表 4-3 所示。
478967fe596b433ca6d97d3b1cf50ba2.png

1bff45a1ca6d40bbb1c6b67530b71198.png

接下来,以 XML 文档 bookstore.xml 为例,为大家演示如何使用表 4-3 中的表达式选取
XML 文档中的节点。bookstore.xml 的具体内容如下。
<?xml version="1.0" encoding="ISO-8859-1"?> 
<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>

        选取节点的示例代码如下。

 1 bookstore # 选取 bookstore 的所有子节点2 /bookstore # 选取根节点 bookstore 3 bookstore/book # 从根节点 bookstore 开始,向下选取名为 book 的所有子节点4 //book # 从任意节点开始,选取名为 book 的所有子节点5 bookstore//book # 从 bookstore 的后代节点中,选取名为 book 的所有子节点6 //@lang # 选取所有名为 lang 的属性节点
在上述代码中,第 3 行、第 4 行的路径表达式具有相同的功能,都可以选取节点 book 的所
有子节点。前者是从根节点开始沿着路径向下选取的,后者是从节点树的任意位置开始选取的。

2.谓语

谓语是为路径表达式附加的条件,主要用于筛选当前被处理的节点集,选取出满足某个
特定条件的节点,或者包含了指定属性或值的节点。谓语会嵌入方括号中,位于要补充说明
的节点后面。带谓语的路径表达式的语法格式如下:
节点[谓语]
在上述格式中,方括号中的谓语可以是整数、属性、函数,也可以是整数、属性、函数
与运算符组合的表达式。如果谓语是整数(从 1 开始),则这个数值将作为位置,用于从节点
集中选取与该位置对应的节点;如果是属性,则会从节点集中选取包含该属性的节点;如果
是函数,则会将该函数的返回值作为条件,从节点集中选取满足条件的节点。常用的 XPath
函数如表 4-4 所示。
e74661f6bf7e441195b30240688b518e.png

8f36aad2166e42e2b81d75efe0303246.png

接下来,以前面的 bookstore.xml 为例,为大家演示带谓语的路径表达式的用法,具体代
码如下。
/bookstore/book[1] # 选取属于 bookstore 子节点的第 1 个 book 节点
/bookstore/book[last()] # 选取属于 bookstore 子节点的最后一个 book 节点
/bookstore/book[last()-1] # 选取属于 bookstore 子节点的倒数第 2 个 book 节点
/bookstore/book[position()<3] # 选取属于 bookstore 子节点的前两个 book 节点
//title[@lang] # 选取所有的属性名称为 lang 的 title 节点
//title[@lang= 'eng'] # 选取所有的属性名称为 lang 且属性值为 eng 的 title 节点
# 选取子节点 price 的值大于 35.00,且父节点为 bookstore 的所有 book 节点
/bookstore/book[price>35.00] 
# 选取属于 book 的所有子节点 title,且节点 book 的子节点 price 的值必须大于 35.00 
/bookstore/book[price>35.00]/title

3.选取未知节点

表 4-5 选取未知节点的通配符和函数
通配符/函数说明
*
匹配任何元素节点
@*
匹配任何属性节点
node()
匹配任何类型的节点

        XPath 提供了选取未知节点的通配符和函数,关于它们的说明如表 4-5 所示。

        以前面的 XML 文档为例,演示表 4-5 中通配符和函数的用法,具体代码如下。

/bookstore/* # 选取属于 bookstore 的所有子节点
//* # 选取文档中的所有节点
//title[@*] # 选取所有带有属性的节点 title

4.选取若干路径

在 XPath 中,我们可以使用“|”运算符连接多个路径表达式,根据多个路径选取对应的
节点。以前面的 XML 文档为例,演示“|”运算符的用法,具体代码如下。
//book/title | //book/price # 选取属于 book 的子节点 title 和 price 
//title | //price # 选取所有 title 节点和 price 节点
# 选取属于/bookstore/book/的所有 title 节点和文档中的所有 price 节点
/bookstore/book/title | //price

 

 

 

 

 

 

 

 

 

 

 

相关文章:

  • 【微信小程序开发实战项目】——如何制作一个属于自己的花店微信小程序(1)
  • 深度学习21-30
  • 先导小型工业4.0教学生产线助力制造业技术创新
  • 老年生活照护实训室:探索现代养老服务的奥秘
  • NAS安全存储怎样实现更精细的数据权限管控?
  • Grafana面试题精选和参考答案
  • 【计算机视觉】mmcv库详细介绍
  • sqlmap常用参数及示例
  • 重温react-07(函数注释和useEffect的使用方式)
  • 秋招Java后端开发冲刺——非关系型数据库篇(Redis)
  • SSM OA办公系统19159
  • 使用ECharts实现动态数据可视化的最佳实践
  • 2024年建筑八大员(质量员-土建专业)考试题库。全面提升考试成绩,轻松过级!
  • js删除el-table删除新增项,有的已经保存有的未经保存
  • php开发的系统/软件如何实现闭源?
  • HTTP那些事
  • If…else
  • iOS高仿微信项目、阴影圆角渐变色效果、卡片动画、波浪动画、路由框架等源码...
  • Joomla 2.x, 3.x useful code cheatsheet
  • leetcode386. Lexicographical Numbers
  • SQLServer之创建显式事务
  • 百度小程序遇到的问题
  • 回顾 Swift 多平台移植进度 #2
  • 看完九篇字体系列的文章,你还觉得我是在说字体?
  • 每天一个设计模式之命令模式
  • 排序算法学习笔记
  • 手机端车牌号码键盘的vue组件
  • 数据科学 第 3 章 11 字符串处理
  • 微信小程序填坑清单
  • 学习笔记:对象,原型和继承(1)
  • 一个JAVA程序员成长之路分享
  • 优化 Vue 项目编译文件大小
  • 资深实践篇 | 基于Kubernetes 1.61的Kubernetes Scheduler 调度详解 ...
  • ## 临床数据 两两比较 加显著性boxplot加显著性
  • #07【面试问题整理】嵌入式软件工程师
  • $(function(){})与(function($){....})(jQuery)的区别
  • $HTTP_POST_VARS['']和$_POST['']的区别
  • (C#)if (this == null)?你在逗我,this 怎么可能为 null!用 IL 编译和反编译看穿一切
  • (动手学习深度学习)第13章 计算机视觉---图像增广与微调
  • (附源码)python旅游推荐系统 毕业设计 250623
  • (没学懂,待填坑)【动态规划】数位动态规划
  • (十三)Maven插件解析运行机制
  • (学习日记)2024.03.25:UCOSIII第二十二节:系统启动流程详解
  • (一)WLAN定义和基本架构转
  • (转)3D模板阴影原理
  • .apk 成为历史!
  • .net core 客户端缓存、服务器端响应缓存、服务器内存缓存
  • .NET Core中Emit的使用
  • .net Signalr 使用笔记
  • .stream().map与.stream().flatMap的使用
  • /var/lib/dpkg/lock 锁定问题
  • [3D基础]理解计算机3D图形学中的坐标系变换
  • [BZOJ1178][Apio2009]CONVENTION会议中心
  • [C#C++]类CLASS
  • [C++]模板与STL简介