深圳幻海软件技术有限公司 欢迎您!

Selenium中常用定位器Xpath的完整使用指南

2023-02-28

译者|陈峻审校|孙淑娟在编写Selenium类型的自动化脚本时,我们往往需要使用各种定位元素。不过在我们无法使用id、class、name等定位器实现定位的情况下,则可以使用XPath来定位网页上的某个元素。虽然XPath并非是唯一能够为Selenium提供元素发现功能的过程,但是它确实能够通过提供

译者 | 陈峻

审校 | 孙淑娟

在编写Selenium类型的自动化脚本时,我们往往需要使用各种定位元素。不过在我们无法使用id、class、name等定位器实现定位的情况下,则可以使用XPath来定位网页上的某个元素。虽然XPath并非是唯一能够为Selenium提供元素发现功能的过程,但是它确实能够通过提供灵活的定位器,来支持针对某种条件(如,动态搜索某个Web元素)的定位需求。

下面,我将和您讨论如何使用XPath的各种表达式,来定位复杂的、或动态的项目。而此类项目的普遍特征是会随着操作、或页面的刷新,而动态发生变化。

什么是XPath?

作为Selenium中最常用的定位器之一,Xpath(也称为XML path)通过为页面提供HTML格式的代码,来支持由您所定义的各项查找。也就是说,通过使用HTML的DOM结构,您可以针对HTML和XML文档定位网页中的每个元素。下图展示了XPath的标准语法:

由上图可知,其中:

  1. //:表示当前的节点
  2. Tagname:表示单个节点的标签名称
  3. @:表示选择属性。
  4. Attribute:表示节点的属性
  5. 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的表达式:

Absolute Xpath: /html/body/div/header/div/div/div[2]/div/div/div[2]/nav/div/div/ul/li[8]/a
  • 1.

​相对XPath

由于相对XPath能够从HTML的DOM结构中间开始,因此避免了冗长的XPath。其开头的双斜杠(//)表示它可以在网站的任何位置,去搜索指定元素。

下面展示了一个相对XPath的表达式:

Relative XPath:  //*[@id=”primary-menu-single”]/li[8]/a
  • 1.

如何在Selenium中编写XPath?

下面,我们来了解一下如何在Selenium中编写XPath。

基本XPath

使用基本XPath的表达式,您可以从XML文档中选择节点、或节点列表,请参考下图:

下面展示了其他一些简单的XPath表达式:

Xpath = //input[@type=’email’]
Xpath = //textarea[@class= ‘wpcf7-form-control wpcf7-textarea’]
Xpath =  //input[@value=’Submit Now’]
Xpath = //a[@href=’https://qacraft.com/’]
  • 1.
  • 2.
  • 3.
  • 4.

Xpath使用contains()

当属性值发生动态变化时,我们可以采用XPath中所提供的被称为contains()的方法,来定位一个具有不完整文本的元素。

如下图所示,name的完整值是“your-website”,但是我们只使用其部分值--“website”。其对应的XPath表达式为:

//input[contains(@name, ‘website’)]
  • 1.

Xpath使用OR和AND

在使用OR表达式时,Xpath会判断OR前后的两个条件,即:仅在前一个、或后一个条件为真,或者是两者都为真时,才能识别到目标元素。例如,您可以使用如下XPath中的OR表达式,来确定是有一个、还是两个条件为真。

下图突出显示了两个基础的组件:

Xpath: //*[@type='email' or @name='your-name']
  • 1.

而如下的AND语句要同时判断两个条件,并且只有两个条件都必须为真时,才能识别特定的元素。

Xpath: //input[@type='text' and @name='your-name']
  • 1.

下图突出显示了具有“type”和“name”属性的“Name”元素。可见,AND表达式会在两个条件都为真时,去查找相关元素。

XPath使用starts-with函数

我们可以使用该函数,来识别自上次刷新了页面、或在页面上进行任何操作期间,发生了变化的元素。而如果属性值根本就没有发生改变,您仍然可以将此公式用于静态属性值。例如,某个特定元素的类的数值会发生如下有规律的变化:

Class = ‘wpcf7’
Class = ‘wpcf8’
Class = ‘wpcf9’
  • 1.
  • 2.
  • 3.

那么在下面的表达式中,有5个组件的“data-name”属性值是以“your”开头的:

Xpath: //span[starts-with(@data-name ,'your' )]
  • 1.

Xpath使用text()

通过使用元素的实际文本,我们可以在表达式中发现各种元素。此处可以被使用的元素文本包括:名称、用户名、电子邮件等标签,或是带有“保存”或“提交”等文本的按钮、以及表单的标签。下面展示了此类表达式的一个示例:

Xpath: //span[text()=’Contact us’]
  • 1.

Xpath使用索引

通过索引,Xpath可被用于定位某个列表中的特定元素。其指示性的语法表达式为:

XPath: (//*[@attribute='value'])[index]
  • 1.

由于表达式中有许多输入标签具有相同的属性值,因此我们可以使用索引来定位元素。例如,如果您想使用一个属性来生成5个不同的元素,而您实际上只需要用到其中的第2或第3个时,就可以使用索引来定位该元素。

Xpath: (//input[@type=’text’])[2]
  • 1.

如下图所示,表达式根据“type”属性找到了3个元素,而我们只想要其中的第2个元素,因此便可以使用索引2来发现它。

在Selenium中编写XPath的Axes方法

在一些复杂的XPath中,我们可以使用如下语法表达式,去找到当前节点的下一个元素。

Syntax: //tagname[@attribute=’value’]//following::tagname
  • 1.

在下面的示例中,我们试着通过使用当前节点的名称,来定位电子邮件地址。

Xpath: //input[@name='your-name']//following::input[1]
  • 1.

XPath使用following-sibling

我们可以通过使用following-sibling的如下语法,从当前节点之后的同一级节点中查找某个元素。

Syntax: //tagname[@attribute=’value’]//following-sibiling::tagname
  • 1.

Xpath使用preceding

我们可以通过使用preceding的如下语法,来定位当前节点之前的元素。

Syntax://tagname[@attribute='value']//preceding::tagname
  • 1.

在下面的示例中,我们使用当前节点的电话号码,来试着定位电子邮件地址。

Xpath: //input[@name=’your-phone’]//preceding::input[1]
  • 1.

如下图所示,电话号码是XPath中的当前节点,而电子邮件地址在该节点之前,因此我们可以通过preceding找到。

Xpath使用peceding-sibling

我们可以通过使用previous-sibling的如下语法表达式,查找当前节点之前的同级别元素。

Syntax://tagname[@attribute='value']//previous-sibling::tagname
  • 1.

如下图所示,我们使用当前节点,来试着定位“Website Testing”标签。

XPath使用child

我们可以通过使用child的如下语法,来定位特定节点的每个子元素。

Syntax: //tagname[@attribute='value']//child::tagname
  • 1.

在如下示例中,input是父节点span的子节点,我们需要使用child表达式,来获取name元素。

Xpath: //span[@data-name='your-name']//child::input
  • 1.

XPath使用Parent

我们可以通过使用parent的如下语法,找到当前节点的父节点。

Syntax://tagname[@attribute='value']/parent::tagname
  • 1.

在下面的示例中,我们通过使用parent的表达式,可以通过子节点来确定父节点的div。此处的span是子节点。

Xpath: //span[@data-name='your-name']//parent::div
  • 1.

如何捕获加载器图像(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