Python+Selenium基础篇之6-元素定位方法

Python68

WebDriver 提供了 8 种元素定位方法,在 Python 中,对应的方法如下:
 id 定位 → find_element_by_id()
 name 定位 → find_element_by_name()
 tag 定位 → find_element_by_tag_name()
 class 定位 → find_element_by_class_name()
 link_text → find_element_by_link_text()
 partial link 定位 → find_element_by_partial_link_text()
 XPath 定位 → find_element_by_xpath()
 CSS_selector 定位 → find_element_by_css_selector()

如果把页面上的元素看作人,那么在现实世界中如何找到某人呢?
首先,可以通过人本身的属性进行查找,例如他的姓名、手机号、身份证号等,这些都是用于区别于他人的属性。在 Web 页面上的元素也有本身的属性,例如,id、name、class name、tag name 等。其次,可以通过位置进行查找,例如,x 国、x 市、x 路、x 号。XPath 和 CSS 可以通过标签层级关系的方式来查找元素。最后,还可以借助相关人的属性来找到某人。例如,我没有小明的联系方式,但是我有他爸爸的手机号,那么通过他爸爸的手机号最终也可以找到小明。XPath 和 CSS 同样提供了相似的定位策略来查找元素。

属性定位

HTML 规定, id 在 HTML 文档中必须是唯一的,这类似于我国公民的身份证号,具有唯一性。WebDriver 提供的 id 定位方法是通过元素的 id 来查找元素的。

HTML 规定,name 用来指定元素的名称,因此它的作用更像是人的姓名。

HTML 规定,class 用来指定元素的类名,其用法与 id、name 类似。

HTML 通过 tag 来定义不同页面的元素。例如,​ &#x200B;<input>&#x200B;​​一般用来定义输入框,​ &#x200B;<a>&#x200B;</a>​​标签用来定义超链接等。不过,因为一个标签往往用来定义一类功能,所以通过标签识别单个元素的概率很低。例如,我们打开任意一个页面,查看前端代码时都会发现大量的​ &#x200B;<div>&#x200B;</div>​​、​ &#x200B;<input>&#x200B;​​、​ &#x200B;<a>&#x200B;</a>​等标签。

link 定位与前面介绍的几种定位方法有所不同,它专门用来定位文本链接。百度输入框上面的几个文字链接的代码如下。

Python+Selenium基础篇之6-元素定位方法

Python+Selenium基础篇之6-元素定位方法

partial link 定位是对 link 定位的一种补充,有些文字链接比较长,这个时候我们可以取文字链接的部分文字进行定位,只要这部分文字可以唯一地标识这个链接即可。

在理想状态下,一个页面当中每个元素都有唯一的 id 值和 name 值,可以通过它们来查找元素。但在实际项目中并非想象得这般美好,有时候一个元素没有 id 值和 name 值,或者页面上有多个元素属性是相同的;又或者 id 值是随机变化的,在这种情况下,如何定位元素呢?

XPath 定位

绝对路径定位

如果把元素看作人,假设这个人没有任何属性特征(手机号、姓名、身份证号),但这个人一定存在于某个地理位置,如 xx 省 xx 市 xx 区 xx 路 xx 号。对于页面上的元素而言,也会有这样一个绝对地址。

Python+Selenium基础篇之6-元素定位方法

利用元素属性定位

除使用绝对路径外,XPath 还可以使用元素的属性值来定位。

Python+Selenium基础篇之6-元素定位方法

//input 表示当前页面某个 input 标签,[@id='kw'] 表示这个元素的 id 值是 kw。如果不想指定标签名,那么可以用星号(*)代替。当然,使用 XPath 不局限于 id、name和 class 这三个属性值,元素的任意属性都可以使用,只要它能唯一标识一个元素。

层级与属性结合

如果一个元素本身没有可以唯一标识这个元素的属性值,那么我们可以查找其上一级元素。如果它的上一级元素有可以唯一标识属性的值,就可以拿来使用。

Python+Selenium基础篇之6-元素定位方法

假如百度输入框没有可利用的属性值,那么可以查找它的上一级属性。例如,小明刚出生的时候没有名字,也没有身份证号,那么亲朋好友来找小明时可以先找到小明的爸爸,因为他爸爸是有很多属性特征的。找到小明的爸爸后,就可以找到小明了。通过 XPath 描述如下:​ &#x200B;find_element_by_xpath("//span[@class='bg s_ipt_wr']/input")&#x200B;​ span[@class='s_ipt_wr'] 通过 class 定位到父元素,后面的/input 表示父元素下面的子元素。如果父元素没有可利用的属性值,那么可以继续向上查找父元素的父元素。

使用逻辑运算符

如果一个属性不能唯一区分一个元素,那么我们可以使用逻辑运算符连接多个属性来查找元素:​ &#x200B;find_element_by_xpath("//input[@id='kw' and @class='s_ipt']")&#x200B;

使用 contains 方法

contains 方法用于匹配一个属性中包含的字符串。例如,span 标签的 class 属性为"bgs_ipt_wr":​ &#x200B;find_element_by_xpath("//span[contains(@calss,'s_ipt_wr')]/input")&#x200B;​,contains 方法只取了 class 属性中的"s_ipt_wr"部分。

使用 text()方法

text()方法用于匹配显示文本信息。例如,前面通过 link text 定位的文字链接:​ &#x200B;find_element_by_xpath("//a[text(),'&#x65B0;&#x95FB;')]")&#x200B;​​。当然,contains 和 text()也可以配合使用:​ &#x200B;find_element_by_xpath("//a[contains(text(),'&#x4E00;&#x4E2A;&#x5F88;&#x957F;&#x7684;')]")&#x200B;​。

CSS 定位

CSS 选择器可以较为灵活地选择控件的任意属性,一般情况下,CSS 定位速度比 XPath定位速度快。CSS 选择器的更多用法可以查看 W3CSchool 网站中的 CSS 选择器参考手册(http://www.w3school.com.cn/cssref/css_selectors.asp)。

Python+Selenium基础篇之6-元素定位方法

通过 class 定位

find_element_by_css_selector()方法用于在 CSS 中定位元素,点号(.)表示通过 class来定位元素。

find_element_by_css_selector(".s_ipt")find_element_by_css_selector(".s_btn")

通过 id 定位

井号(#)表示通过 id 来定位元素。

find_element_by_css_selector("#kw")find_element_by_css_selector("#su")

通过标签名定位

CSS 中,用标签名定位元素时不需要任何符号标识,直接使用标签名即可:​ &#x200B;find_element_by_css_selector("input")&#x200B;​。

通过标签层级关系定位

&#x200B;find_element_by_css_selector("span > input")&#x200B;​这种写法表示有父元素,父元素的标签名为 span。查找 span 中所有标签名为 input 的子元素。

通过属性定位

在 CSS 中可以使用元素的任意属性定位,只要这些属性可以唯一标识这个元素。对属性值来说,可以加引号,也可以不加,注意和整个字符串的引号进行区分。

find_element_by_css_selector("[autocomplete=off]")find_element_by_css_selector("[name='kw']")find_element_by_css_selector('[type="submit"]')

组合定位

我们可以把上面的定位策略组合起来使用,这就大大加强了定位元素的唯一性。我们要定位的这个元素标签名为 input,这个元素的 class 属性为 s_ipt;并且它有一个父元素,标签名为 span。它的父元素还有父元素,标签名为 form,class 属性为 fm。我们要找的就是必须满足这些条件的一个元素。

find_element_by_css_selector("form.fm > span > input.s_ipt")find_element_by_css_selector("form#form > span > input#kw")

更多定位用法

查找 class 属性包含"s_ipt_wr"字符串的元素。​ &#x200B;find_element_by_css_selector("[class*=s_ipt_wr]")&#x200B;​​ 查找 class 属性以"bg"字符串开头的元素。​ &#x200B;find_element_by_css_selector("[class^=bg]")&#x200B;​ 查找 class 属性以"wrap"字符串结尾的元素。​ &#x200B;find_element_by_css_selector("[class$=wrap]")&#x200B;​ 查找 form 标签下面第 2 个 input 标签的元素。​ &#x200B;find_element_by_css_selector("form > input:nth-child(2)")&#x200B;

用 By 定位元素

针对前面介绍的 8 种定位方法,WebDriver 还提供了另外一套写法,即统一调用find_element()方法,通过 By 来声明定位,并且传入对应定位方法的定位参数,具体如下。find_element()方法只用于定位元素,它需要两个参数。第一个参数是定位的类型,由By 提供(​ &#x200B;from selenium.webdriver.common.by import By&#x200B;​);第二个参数是定位的值。

Python+Selenium基础篇之6-元素定位方法

本博客摘抄自《Selenium3自动化测试实战——基于Python语言》,详细内容请购买该书进行学习

Original: https://blog.51cto.com/feishujun/5513653
Author: mb62de8abf75c00
Title: Python+Selenium基础篇之6-元素定位方法