定位元素是任何与Web进行交互操作的基础,JavaScript如是,对于Selenium亦如是。只有定位到了元素,才能对元素进行操作。
Selenium中的两个基础元素定位方法(find_element与 find_elements)
在Selenium中使用find_element与 find_elements方法即可完成元素的定位。
我们先简单对比下这两个方法,再讲相关的细节:
find_element:- 函数签名:
def find_element(self, by=By.ID, value=None): - 函数参数:
by为定位策略,value为定位策略对应的定位器 - 调用对象:
WebDriver实例或WebElement对象 - 返回值:定位到元素时返回单个
WebElement对象,没有定位到元素时抛出NoSuchElementException异常
- 函数签名:
find_elements:- 函数签名:
def find_elements(self, by=By.ID, value=None): - 函数参数:
by为定位策略,value为定位策略对应的定位器 - 调用对象:
WebDriver实例或WebElement对象 - 返回值:定位到元素时返回
WebElement对象列表,没有定位到元素时返回空列表
- 函数签名:
返回值的差异
从上述函数的基本特性可知,这两个方法的参数,调用对象完全一样,差别主要在返回值上。返回值上的差异跟JavaScript中DOM的操作方法有些类似,element返回单个对象,elements返回对象列表,这是非常容易区别的差异。
find_element定位到元素的话,仅返回单个WebElement对象,没定位到元素就抛出异常。
find_elements定位到元素时返回WebElement对象列表,没有定位到元素时返回空列表。
调用对象
这两个方法的调用对象都可以为WebDriver实例或WebElement对象。
WebDriver实例我们可以认为就是Selenium启动的浏览器,这浏览器不单只是包含界面、控制等内容,最重要的是包含当前打开的页面。我们需要定位的元素(DOM 节点)就在这个页面中。因此,初始我们应该使用WebDriver实例调用这两个元素定位方法定位元素,得到返回的页面元素WebElement对象。由于页面元素是可以嵌套的,相应WebElement对象应该也可以定位元素。
根据selenium\webdriver\remote\webdriver.py和selenium\webdriver\remote\webelement.py源码可知,WebDriver对象和WebElement对象都具有find_element与 find_elements方法。 在Selenium中,这种设计方式被称为基于角色的接口。
Selenium中的定位策略
在前面讲到的两个方法中,都具有By参数,及定位策略 。Selenium中的定位策略定义在selenium\webdriver\common\by.py中。在使用定位策略时,可以导入By类 from selenium.webdriver.common.by import By
class By(object):
"""
Set of supported locator strategies.
"""
ID = "id"
XPATH = "xpath"
LINK_TEXT = "link text"
PARTIAL_LINK_TEXT = "partial link text"
NAME = "name"
TAG_NAME = "tag name"
CLASS_NAME = "class name"
CSS_SELECTOR = "css selector"
| 定位器 Locator | 描述 |
|---|---|
| class name | 定位class属性与搜索值匹配的元素(不允许使用复合类名) |
| css selector | 定位 CSS 选择器匹配的元素 |
| id | 定位 id 属性与搜索值匹配的元素 |
| name | 定位 name 属性与搜索值匹配的元素 |
| link text | 定位link text可视文本与搜索值完全匹配的锚元素 |
| partial link text | 定位link text可视文本部分与搜索值部分匹配的锚点元素。如果匹配多个元素,则只选择第一个元素。 |
| tag name | 定位标签名称与搜索值匹配的元素 |
| xpath | 定位与 XPath 表达式匹配的元素 |
在上述策略中:
id、class name、css selector是比较推荐的策略,因为他们定位的范围较小。
xpath定位在某些情况下可读性、灵活性不强,需要学习xpath语法,但优势是大部分浏览器都支持复制元素的xpath,这样就不用自己编写xpath。
tag name需要谨慎使用,因为按照标签名定位元素,往往返回大量元素。
link text和 partial link text官方都不太建议使用,使用场景狭窄,底层其实是使用xpath实现的。
Selenium中的快捷定位接口
虽然find_element与 find_elements方法已经可以实现元素的定位功能,但是操作来比较繁琐。
因此Selenium根据8种不同的策略提供了16个快捷定位方法。
find_element_by_id(self, id_)
find_elements_by_id(self, id_)
find_element_by_name(self, name)
find_elements_by_name(self, name)
find_element_by_link_text(self, link_text)
find_elements_by_link_text(self, link_text)
find_element_by_partial_link_text(self, link_text)
find_elements_by_partial_link_text(self, link_text)
find_element_by_tag_name(self, name)
find_elements_by_tag_name(self, name)
find_element_by_xpath(self, xpath)
find_elements_by_xpath(self, xpath)
find_element_by_class_name(self, name)
find_elements_by_class_name(self, name)
find_element_by_css_selector(self, css_selector)
find_elements_by_css_selector(self, css_selector)
通过源码即可验证这些快捷方法与find_element、find_elements之间的关系。
def find_element_by_id(self, id_):
return self.find_element(by=By.ID, value=id_)
def find_elements_by_id(self, id_):
return self.find_elements(by=By.ID, value=id_)
简易案例
from selenium import webdriver
from selenium.webdriver.common.by import By
driver = webdriver.Firefox()
driver.get("http://www.baidu.com")
btn1 = driver.find_element(By.ID, "su")
print(type(btn1))
btns1 = driver.find_elements(By.ID, "su")
print(type(btns1), len(btns1), type(btns1[0]))
btn2 = driver.find_element_by_id("su")
print(type(btn2))
btns2 = driver.find_elements_by_id("su")
print(type(btns2), len(btns2), type(btns2[0]))
本文介绍Selenium中元素定位的方法,包括find_element与find_elements的区别及其使用场景,并提供多种定位策略和快捷定位接口。
1万+

被折叠的 条评论
为什么被折叠?



