审校 | 孙淑娟
在编写Selenium类型的自动化脚本时,我们往往需要使用各种定位元素。不过在我们无法使用id、class、name等定位器实现定位的情况下,则可以使用XPath来定位网页上的某个元素。虽然XPath并非是唯一能够为Selenium提供元素发现功能的过程,但是它确实能够通过提供灵活的定位器,来支持针对某种条件(如,动态搜索某个Web元素)的定位需求。
下面,我将和您讨论如何使用XPath的各种表达式,来定位复杂的、或动态的项目。而此类项目的普遍特征是会随着操作、或页面的刷新,而动态发生变化。
什么是XPath?
作为Selenium中最常用的定位器之一,Xpath(也称为XML path)通过为页面提供HTML格式的代码,来支持由您所定义的各项查找。也就是说,通过使用HTML的DOM结构,您可以针对HTML和XML文档定位网页中的每个元素。下图展示了XPath的标准语法:
由上图可知,其中:
- //:表示当前的节点
- Tagname:表示单个节点的标签名称
- @:表示选择属性。
- Attribute:表示节点的属性
- Value:表示已选择的属性值
为了能够查找Web元素,Selenium提供了如下各种XPath定位器:
XPATH定位器 | 在网页上查找不同的元素 |
ID | 通过使用元素的 ID,来查找元素。 |
Classname | 使用其类名,来查找元素。 |
Name | 使用其名称,来查找元素。 |
Link text | 使用链接的文本,来查找元素。 |
XPath | 查找动态元素、和在不同的网页元素之间移动,都需要使用XPath。 |
CSS path | CSS路径可以发现缺少名称、类或ID的项目。 |
Selenium中的XPath类型
以下是Selenium提供的两种XPath类型:
绝对XPath
绝对XPath是一种从根节点定位元素的快速且简便的技术。其主要缺点在于,如果元素的路径一旦发生变化,则会让Xpath失败并报错。
Xpath的语法以单个正斜杠(/)开头,表示您可以从根节点中选择一个元素。下面展示了一个绝对XPath的表达式:
相对XPath
由于相对XPath能够从HTML的DOM结构中间开始,因此避免了冗长的XPath。其开头的双斜杠(//)表示它可以在网站的任何位置,去搜索指定元素。
下面展示了一个相对XPath的表达式:
如何在Selenium中编写XPath?
下面,我们来了解一下如何在Selenium中编写XPath。
基本XPath
使用基本XPath的表达式,您可以从XML文档中选择节点、或节点列表,请参考下图:
下面展示了其他一些简单的XPath表达式:
Xpath使用contains()
当属性值发生动态变化时,我们可以采用XPath中所提供的被称为contains()的方法,来定位一个具有不完整文本的元素。
如下图所示,name的完整值是“your-website”,但是我们只使用其部分值--“website”。其对应的XPath表达式为:
Xpath使用OR和AND
在使用OR表达式时,Xpath会判断OR前后的两个条件,即:仅在前一个、或后一个条件为真,或者是两者都为真时,才能识别到目标元素。例如,您可以使用如下XPath中的OR表达式,来确定是有一个、还是两个条件为真。
下图突出显示了两个基础的组件:
而如下的AND语句要同时判断两个条件,并且只有两个条件都必须为真时,才能识别特定的元素。
下图突出显示了具有“type”和“name”属性的“Name”元素。可见,AND表达式会在两个条件都为真时,去查找相关元素。
XPath使用starts-with函数
我们可以使用该函数,来识别自上次刷新了页面、或在页面上进行任何操作期间,发生了变化的元素。而如果属性值根本就没有发生改变,您仍然可以将此公式用于静态属性值。例如,某个特定元素的类的数值会发生如下有规律的变化:
那么在下面的表达式中,有5个组件的“data-name”属性值是以“your”开头的:
Xpath使用text()
通过使用元素的实际文本,我们可以在表达式中发现各种元素。此处可以被使用的元素文本包括:名称、用户名、电子邮件等标签,或是带有“保存”或“提交”等文本的按钮、以及表单的标签。下面展示了此类表达式的一个示例:
Xpath使用索引
通过索引,Xpath可被用于定位某个列表中的特定元素。其指示性的语法表达式为:
由于表达式中有许多输入标签具有相同的属性值,因此我们可以使用索引来定位元素。例如,如果您想使用一个属性来生成5个不同的元素,而您实际上只需要用到其中的第2或第3个时,就可以使用索引来定位该元素。
如下图所示,表达式根据“type”属性找到了3个元素,而我们只想要其中的第2个元素,因此便可以使用索引2来发现它。
在Selenium中编写XPath的Axes方法
在一些复杂的XPath中,我们可以使用如下语法表达式,去找到当前节点的下一个元素。
在下面的示例中,我们试着通过使用当前节点的名称,来定位电子邮件地址。
XPath使用following-sibling
我们可以通过使用following-sibling的如下语法,从当前节点之后的同一级节点中查找某个元素。
Xpath使用preceding
我们可以通过使用preceding的如下语法,来定位当前节点之前的元素。
在下面的示例中,我们使用当前节点的电话号码,来试着定位电子邮件地址。
如下图所示,电话号码是XPath中的当前节点,而电子邮件地址在该节点之前,因此我们可以通过preceding找到。
Xpath使用peceding-sibling
我们可以通过使用previous-sibling的如下语法表达式,查找当前节点之前的同级别元素。
如下图所示,我们使用当前节点,来试着定位“Website Testing”标签。
XPath使用child
我们可以通过使用child的如下语法,来定位特定节点的每个子元素。
在如下示例中,input是父节点span的子节点,我们需要使用child表达式,来获取name元素。
XPath使用Parent
我们可以通过使用parent的如下语法,找到当前节点的父节点。
在下面的示例中,我们通过使用parent的表达式,可以通过子节点来确定父节点的div。此处的span是子节点。
如何捕获加载器图像(Loader Images)
有时候,当我们在自动化Selenium网站时,会让屏幕上短暂显示一些元素。对此,我们可以试着为正在加载中的图像识别XPath,毕竟它们需要一段时间才会显示在屏幕上。下面,我列出了为加载器查找XPath的步骤:
第 1 步: 在首次加载页面时,请按下F12以检查元素。接着,请选择资源选项卡以查看下图。
第 2 步: 当我们在屏幕上看到正在加载的元素时,只需按下F8、或点击下图中被圈出的暂停键,以显示其位置。
第 3 步: 返回元素页面,并开始在此编写定位器。
第 4 步: 在XPath完成之后,返回并从资源中选择恢复选项。
通过上述方法,我们便在查找元素的XPath时,暂停执行,并将元素保留在屏幕上了。
小结
在上述关于Selenium定位器的介绍中,我们了解了不同类型的XPath。利用它们,我们可以使用contains()、Start-with()和text()去创建简单的XPath,以及使用preceding和following创建更为复杂的XPath。同时,我们也介绍了如何定位动态元素。希望上述内容能够为您学习和使用XPath提供帮助。
译者介绍
陈峻 (Julian Chen),51CTO社区编辑,具有十多年的IT项目实施经验,善于对内外部资源与风险实施管控,专注传播网络与信息安全知识与经验。
原文Xpath in Selenium: A Complete Guide,作者:Twisa Mistry