Selenium3 Python WebDriver API源码探析(3):定位Web元素

本文介绍Selenium中元素定位的方法,包括find_element与find_elements的区别及其使用场景,并提供多种定位策略和快捷定位接口。
部署运行你感兴趣的模型镜像

定位元素是任何与Web进行交互操作的基础,JavaScript如是,对于Selenium亦如是。只有定位到了元素,才能对元素进行操作。

Selenium中的两个基础元素定位方法(find_elementfind_elements

Selenium中使用find_elementfind_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.pyselenium\webdriver\remote\webelement.py源码可知,WebDriver对象和WebElement对象都具有find_elementfind_elements方法。Selenium中,这种设计方式被称为基于角色的接口。

Selenium中的定位策略

在前面讲到的两个方法中,都具有By参数,及定位策略 。Selenium中的定位策略定义在selenium\webdriver\common\by.py中。在使用定位策略时,可以导入Byfrom 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 表达式匹配的元素

在上述策略中:
idclass namecss selector是比较推荐的策略,因为他们定位的范围较小。
xpath定位在某些情况下可读性、灵活性不强,需要学习xpath语法,但优势是大部分浏览器都支持复制元素的xpath,这样就不用自己编写xpath
tag name需要谨慎使用,因为按照标签名定位元素,往往返回大量元素。
link textpartial link text官方都不太建议使用,使用场景狭窄,底层其实是使用xpath实现的。

Selenium中的快捷定位接口

虽然find_elementfind_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_elementfind_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]))

您可能感兴趣的与本文相关的镜像

Python3.8

Python3.8

Conda
Python

Python 是一种高级、解释型、通用的编程语言,以其简洁易读的语法而闻名,适用于广泛的应用,包括Web开发、数据分析、人工智能和自动化脚本

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值