如果你还想从头学起Selenium,可以看看这个系列的文章哦!
https://www.cnblogs.com/poloyy/category/1680176.html
其次,如果你不懂前端基础知识,需要自己去补充哦,博主暂时没有总结(虽然我也会,所以我学selenium就不用复习前端了哈哈哈...)
为什么需要设置元素等待?
sleep()
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
__title__ =
__Time__ = 2020/3/25 17:52
__Author__ = 小菠萝测试笔记
__Blog__ = https://www.cnblogs.com/poloyy/
"""
from time import sleep
from selenium import webdriver
driver = webdriver.Chrome("../resources/chromedriver.exe")
20)
# 访问网址
driver.get("http://www.baidu.com")
# ===强制等待3秒才执行下一步===
sleep(3)
# 找到搜索框
inputElement = driver.find_element_by_id("kw")
如果在规定时间内,整个网页都加载完成,则执行下一步,否则会抛出异常
可以把隐式等待当做全局变量,它影响整个页面,所以程序需要等待整个页面加载完成(就是浏览器标签栏那个小圈不再转)时,才会执行下一步【页面加载完成,才能执行下一步】 但可能页面加载未完成的时候,需要定位的元素已经加载完成了,但受限于某些JS文件、图片加载特别慢,我们不能执行下一步,必须得等到网页所有东西都加载完了才能下一步【增加不必要的加载时间】
很简单,就调用一个方法即可,毕竟是作用于WebDriver的
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
__title__ =
__Time__ = 2020/3/25 17:52
__Author__ = 小菠萝测试笔记
__Blog__ = https://www.cnblogs.com/poloyy/
"""
from selenium import webdriver
# 加载驱动
driver = webdriver.Chrome("../resources/chromedriver.exe")
# ===隐性等待20s===
driver.implicitly_wait(20)
# 访问网址
driver.get("http://www.baidu.com")
# 找到搜索框
inputElement = driver.find_element_by_id("kw")
相比隐式等待,显式等待只对指定元素生效,不再是在整个WebDriver生命周期内生效【仅对元素生效】
可以根据需要定位的元素来设置显式等待,无需等待页面完全加载,节省大量因加载无关紧要文件而浪费掉的时间【针对元素设置,无需等待页面加载完成,节省加载时间】
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
__title__ =
__Time__ = 2020/3/25 17:52
__Author__ = 小菠萝测试笔记
__Blog__ = https://www.cnblogs.com/poloyy/
"""
from time import sleep
from selenium import webdriver
# 加载驱动
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
driver = webdriver.Chrome("../resources/chromedriver.exe")
# 访问网址
driver.get("http://www.baidu.com")
# ===显式等待===
# 设置元素等待实例,最多等10秒,每0.5秒查看条件是否成立
element = WebDriverWait(driver, 10, 0.5).until(
# 条件:直到元素加载完成
EC.presence_of_element_located((By.ID, "kw"))
)
class WebDriverWait(object):
def __init__(self, driver, timeout, poll_frequency=POLL_FREQUENCY, ignored_exceptions=None):
"""Constructor, takes a WebDriver instance and timeout in seconds.
:Args:
- driver - Instance of WebDriver (Ie, Firefox, Chrome or Remote)
- timeout - Number of seconds before timing out
- poll_frequency - sleep interval between calls
By default, it is 0.5 second.
- ignored_exceptions - iterable structure of exception classes ignored during calls.
By default, it contains NoSuchElementException only.
until_not()
NoSuchElementException
until()
WebDriverWait(driver实例, 超时时长, 调用频率, 忽略的异常).until(要调用的 方法, 超时时返回的信息)
作用:每隔一段时间(上面的poll_frequency)调用method,直到返回值不为False或不为空
method:需要执行的method
message:抛出异常时的文案,会返回 TimeoutException ,表示超时
注意:这个才是常用的,如:定位元素直到不返回空
作用:调用method,直到返回值为False或为空
method:需要执行的method
message:抛出异常时的文案,会返回 TimeoutException ,表示超时
如果直接传入WebElement(页面元素)对象
WebDriverWait(driver, 10).until(driver.find_element_by_id('kw'))
则会抛出异常
TypeError: 'xxx' object is not callable
method 参数需要传入的对象必须包含 __call()__ 方法 ,什么意思?让对象可以直接被调用
element = WebDriverWait(driver, 10).until(lambda x: x.find_element_by_id("someId"))
is_disappeared = WebDriverWait(driver, 30, 1, (ElementNotVisibleException)).until_not(lambda x: x.find_element_by_id("someId").is_displayed())
可以看到,通过匿名函数也是可以的,可以说比后面介绍的 expected_conditions 模块要方便多了
那么有哪些是包含 __call()__ 的对象呢?
expected_conditions
is_displayed()
是selenium中的一个模块,包含一系列用于判断的条件类,一共26个类
这里就只介绍两个在设置元素等待里面最常用的判断条件类
class presence_of_element_located(object):
""" An expectation for checking that an element is present on the DOM
of a page. This does not necessarily mean that the element is visible.
locator - used to find the element
returns the WebElement once it is located
"""
def __init__(self, locator):
self.locator = locator
def __call__(self, driver):
return _find_element(driver, self.locator)
检查当前DOM树种是否存在该元素(和是否可见没有关系),只要有一个元素加载出来则通过
传入一个元组,格式如下 (By.ID, "元素ID")
By
presence_of_element_located((By.ID, "kw"))
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"
源码几乎一样
class presence_of_all_elements_located(object):
def __init__(self, locator):
self.locator = locator
def __call__(self, driver):
return _find_elements(driver, self.locator)
_find_elements