Translator|陈军审稿人|孙淑娟在编写Selenium类型的自动化脚本时,我们经常需要用到各种定位元素。但是,如果我们不能使用id、class、name等定位器来实现定位,我们可以使用XPath来定位网页中的一个元素。虽然XPath不是唯一可以为Selenium提供元素发现功能的进程,但它通过提供灵活的定位器来支持某些条件下的定位需求(例如动态搜索Web元素)。下面,我将和大家一起探讨如何使用XPath的各种表达式来定位复杂的或动态的项目。此类项目的共同特点是它们会随着操作或页面刷新而动态变化。什么是XPath?作为Selenium中最常用的定位器之一,XPath(也称为XML路径)通过为页面提供HTML格式的代码来支持您定义的搜索。也就是说,通过使用HTML的DOM结构,您可以为HTML和XML文档定位网页中的每个元素。下图是XPath的标准语法:从上图可以看出,其中://:表示当前节点Tagname:表示单个节点的标签名@:表示选择属性。Attribute:表示节点的属性Value:表示选择的属性值为了能够找到Web元素,Selenium提供了以下各种XPath定位器:元素。Classname使用其类名来查找元素。名称使用其名称来查找元素。链接文本使用链接的文本来查找元素。XPath查找动态元素和在不同网页元素之间移动需要使用XPath。CSS路径CSS路径可以找到缺少名称、类或ID的项目。Selenium中的XPath类型以下是Selenium提供的两种XPath类型:AbsoluteXPathAbsoluteXPath是一种快速简便的技术,用于从根节点定位元素。它的主要缺点是如果元素的路径发生变化,会使XPath失败并报错。XPath的语法以单个正斜杠(/)开头,表示您可以从根节点中选择一个元素。下面显示了一个绝对XPath表达式:AbsoluteXPath:/html/body/div/header/div/div/div[2]/div/div/div[2]/nav/div/div/ul/li[8]/aRelativeXPath由于相对XPath可以从HTML的DOM结构的中间开始,因此避免了冗长的XPath。开头的双斜杠(//)表示它可以在网站的任何地方搜索指定的元素。下面是一个相对的XPath表达式:RelativeXPath://*[@id="primary-menu-single"]/li[8]/aSelenium中的XPath怎么写?接下来,我们就来看看如何在Selenium中编写XPath。BasicXPath使用基本的XPath表达式,可以从XML文档中选择一个节点,或者一个节点列表,请参考下图:下面是一些其他简单的XPath表达式:Xpath=//input[@type='email']Xpath=//textarea[@class='wpcf7-form-controlwpcf7-textarea']Xpath=//input[@value='立即提交']Xpath=//a[@href='https://qacraft.com/']Xpath使用contains()当属性值动态变化时,我们可以使用XPath中提供的名为contains()的方法来定位文本不完整的元素。如下图,name的完整值是“your-website”,但我们只使用它的部分值——“website”。对应的XPath表达式为://input[contains(@name,'website')]Xpath使用OR和AND当使用OR表达式时,XPath会判断OR前后两个条件,即:只有在前面,或者后面后一个条件为真,或两者都为真,以识别目标元素。例如,您可以在以下XPath中使用OR表达式来确定一个或两个条件是否为真。下图突出显示了两个基本组件:Xpath://*[@type='email'or@name='your-name']和下面的AND语句需要同时判断两个条件,只有两个条件都可以对于要识别的特定元素必须为真。Xpath://input[@type='text'and@name='your-name']下图突出显示了具有“type”和“name”属性的“Name”元素。可以看出,当两个条件都为真时,AND表达式会找到相关元素。XPath使用starts-with函数我们可以使用此函数来识别自上次页面刷新后或在页面上的任何操作期??间发生更改的元素。但是,如果属性值根本没有变化,您仍然可以将此公式用于静态属性值。例如,某个特定元素的类的值将有规律地变化如下:属性值以“your”开头:Xpath://span[starts-with(@data-name,'your')]Xpath使用text()通过使用元素的实际文本,我们可以在表达式中找到各种元素.可在此处使用的元素文本包括:名称、用户名、电子邮件等标签,或带有“保存”或“提交”等文本的按钮,以及表单标签。此类表达式的示例如下所示:Xpath://span[text()='Contactus']Xpath使用索引传递索引,XPath可用于定位列表中的特定元素。其指示性语法表达式为:XPath:(//*[@attribute='value'])[index]由于表达式中有多个输入标签具有相同的属性值,我们可以使用索引来定位元素。例如,如果你想使用一个属性生成5个不同的元素,但你实际上只需要其中的第2个或第3个,你可以使用索引来定位元素。xpath:(//input[@type='text'])[2]如下图,表达式根据“type”属性找到了3个元素,而我们只想要第二个元素,所以它可以2.用Selenium编写XPath的Axes方法在一些复杂的XPath中,我们可以使用下面的语法表达式来找到当前节点的下一个元素。语法://tagname[@attribute='value']//following::tagname在下面的示例中,我们尝试使用当前节点的名称来定位电子邮件地址。Xpath://input[@name='your-name']//following::input[1]XPath使用following-sibling我们可以使用following-sibling的如下语法从当前节点之后的同级节点开始搜索节点一个元素。语法://tagname[@attribute='value']//following-sibiling::tagnameXpath使用preceding我们可以使用preceding的以下语法来定位当前节点之前的元素。Syntax://tagname[@attribute='value']//preceding::tagname在下面的示例中,我们使用当前节点的电话号码来尝试定位电子邮件地址。Xpath://input[@name='your-phone']//preceding::input[1]如下图,电话号码是XPath中的当前节点,邮箱地址在这个节点之前,所以我们可以通过前面找到。XPath使用peceding-sibling我们可以使用如下previous-sibling的语法表达式来查找当前节点之前的同一级别的元素。语法://tagname[@attribute='value']//previous-sibling::tagname如下图所示,我们使用当前节点尝试定位“WebsiteTesting”标签。XPath使用child我们可以通过使用以下child语法来定位特定节点的每个子元素。语法://tagname[@attribute='value']//child::tagname在下面的例子中,input是父节点span的一个子节点,我们需要使用child表达式来获取name元素。Xpath://span[@data-name='your-name']//child::inputXPath使用Parent,我们可以通过parent的如下语法找到当前节点的父节点。语法://tagname[@attribute='value']/parent::tagname在下面的例子中,我们可以通过parent表达式通过子节点来确定父节点的div。这里的跨度是一个子节点。Xpath://span[@data-name='your-name']//parent::div如何抓取加载器图像(LoaderImages)有时候,我们在自动化Selenium网站的时候,会简单的显示一些在屏幕元素。为此,我们可以尝试为正在加载的图像识别XPath,因为它们需要一段时间才能出现在屏幕上。下面,我列出了为加载程序查找XPath的步骤:第1步:当页面首次加载时,按F12检查元素。接下来,选择Resources选项卡以查看下图。第2步:当我们在屏幕上看到加载元素时,只需按F8,或点击下图中圈出的暂停按钮以显示其位置。第3步:返回元素页面并开始在那里编写定位器。第4步:XPath完成后,返回并从资源中选择还原选项。使用上述方法,我们在查找元素的XPath时暂停执行,并使元素保持在屏幕上。总结在上面对SeleniumLocators的介绍中,我们了解了不同类型的XPath。使用它们,我们可以使用contains()、Start-with()和text()来创建简单的XPath,并使用preceding和following来创建更复杂的XPath。同时,我们也介绍了如何定位动态元素。希望以上内容对您学习和使用XPath有所帮助。译者介绍社区编辑JulianChen。他在实施IT项目方面拥有超过十年的经验。擅长管控内外部资源和风险,注重传播网络与信息安全方面的知识和经验。原标题:XpathinSelenium:ACompleteGuide,作者:TwisaMistry
