首页 > 编程语言 >Python 05 Selenium 等待

Python 05 Selenium 等待

时间:2023-05-22 11:02:36浏览次数:33  
标签:05 Python Selenium 元素 driver EC element located locator


等待

WebDriver 通常可以说有一个阻塞 API。因为它是一个指示浏览器做什么的进程外库,而且 web 平台本质上是异步的,所以 WebDriver 不跟踪 DOM 的实时活动状态。

大多数由于使用 Selenium 和 WebDriver 而产生的间歇性问题都与浏览器和用户指令之间的 竞争条件 有关。例如,用户指示浏览器导航到一个页面,然后在试图查找元素时得到一个 no such element 的错误。

测试文档 race_condition.html:

<!doctype html>
<meta charset=utf-8>
<title>Race Condition Example</title>

<script defer>
  var initialised = false;
  window.addEventListener("load", function() {
    var newElement = document.createElement("p");
    newElement.textContent = "Hello from JavaScript!";
    // 使用 setTimeout() 延时加载
    setTimeout(function(){
      document.body.appendChild(newElement);
      initialised = true;
    },2000)
  });
</script>

代码

from selenium import webdriver
import os

path = os.path.join(os.getcwd(),'race_condition.html')
driver = webdriver.Chrome()
driver.get(path)
el = driver.find_element_by_tag_name("p")
assert el.text == "Hello from JavaScript!"

因为 p 元素是在文档完成加载之后添加的,所以这个 WebDriver 脚本可能是间歇性的。

幸运的是,WebElement 接口上可用的正常指令集——例如 WebElement.click 和 WebElement.sendKeys—是保证同步的,因为直到命令在浏览器中被完成之前函数调用是不会返回的(或者回调是不会在回调形式的语言中触发的)。高级用户交互APIs,键盘和鼠标是例外的,因为它们被明确地设计为“按我说的做”的异步命令。

等待是在继续下一步之前会执行一个自动化任务来消耗一定的时间。

显式等待

显示等待 是 Selenium 客户可以使用的命令式过程语言。它们允许您的代码暂停程序执行,或冻结线程,直到满足通过的 条件 。这个条件会以一定的频率一直被调用,直到等待超时。这意味着只要条件返回一个假值,它就会一直尝试和等待。

由于显式等待允许您等待条件的发生,所以它们非常适合在浏览器及其 DOM 和 WebDrive r脚本之间同步状态。

from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
import os

def document_initialised(driver):
    return driver.execute_script("return initialised")

path = os.path.join(os.getcwd(),'race_condition.html')
driver = webdriver.Chrome()
driver.get(path)
WebDriverWait(driver,10).until(document_initialised)
# no such element: Unable to locate element: {"method":"css selector","selector":"p"}
el = driver.find_element_by_tag_name("p")
# el = wait.until(lambda d: d.find_element_by_tag_name("p"))
assert el.text == "Hello from JavaScript!"

条件 作为函数引用传递, 等待 将会重复运行直到其返回值为 true。“truthful” 返回值是在当前语言中计算为 boolean true 的任何值,例如字符串、数字、boolean、对象(包括 WebElement )或填充(非空)的序列或列表。这意味着 空列表 的计算结果为 false。当条件为 true 且阻塞等待终止时,条件的返回值将成为等待的返回值。

因为等待实用程序默认情况下会忽略 no such element 的错误,所以我们可以重构我们的指令使其更简洁:

from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
import os

path = os.path.join(os.getcwd(),'race_condition.html')
driver = webdriver.Chrome()
driver.get(path)

el = WebDriverWait(driver,10).until(lambda d: d.find_element_by_tag_name("p"))
assert el.text == "Hello from JavaScript!"

传递了一个匿名函数。在多线程环境中,您应该小心操作传入条件的驱动程序引用,而不是外部范围中对驱动程序的引用。

因为等待将会吞没在没有找到元素时引发的 no such element 的错误,这个条件会一直重试直到找到元素为止。然后它将获取一个 WebElement 的返回值,并将其传递回我们的脚本。

如果条件失败,例如从未得到条件为真实的返回值,等待将会抛出/引发一个叫 timeout error 的错误/异常。

预期的条件

由于必须同步 DOM 和指令是相当常见的情况,所以大多数客户端还附带一组预定义的 预期条件 。顾名思义,它们是为频繁等待操作预定义的条件。

from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait

WebDriverWait(driver,10).until(EC.title_is('测试'))

后附 expected_conditions

隐式等待

还有第二种区别于显示等待 类型的 隐式等待 。通过隐式等待,WebDriver 在试图查找_任何_元素时在一定时间内轮询 DOM。当网页上的某些元素不是立即可用并且需要一些时间来加载时是很有用的。

默认情况下隐式等待元素出现是禁用的,它需要在单个会话的基础上手动启用。将显式等待和隐式等待混合在一起会导致意想不到的结果,就是说即使元素可用或条件为真也要等待睡眠的最长时间。

警告: 不要混合使用隐式和显式等待。这样做会导致不可预测的等待时间。例如,将隐式等待设置为10秒,将显式等待设置为15秒,可能会导致在20秒后发生超时。

隐式等待是告诉 WebDriver 如果在查找一个或多个不是立即可用的元素时轮询 DOM 一段时间。默认设置为 0,表示禁用。一旦设置好,隐式等待就被设置为会话的生命周期。

driver = Firefox()
driver.implicitly_wait(10)
driver.get("http://somedomain/url_that_delays_loading")
my_dynamic_element = driver.find_element(By.ID, "myDynamicElement")

流畅等待

流畅等待实例定义了等待条件的最大时间量,以及检查条件的频率。

用户可以配置等待来忽略等待时出现的特定类型的异常,例如在页面上搜索元素时出现的NoSuchElementException。

driver = Firefox()
driver.get("http://somedomain/url_that_delays_loading")
wait = WebDriverWait(driver, 10, poll_frequency=1, ignored_exceptions=[ElementNotVisibleException, ElementNotSelectableException])
element = wait.until(EC.element_to_be_clickable((By.XPATH, "//div")))

expected_conditions

1、title 标题

1)title_is 网页标题是否显示特定内容(必须完全符合)
result = EC.title_is(‘百度一下,你就知道’)
2)title_contains 网页标题是否包含特定内容
result = EC.title_contains(‘百度’)

2、url 网址

1)url_contains 网页网址是否包含特定内容
result = EC.url_contains(‘baidu’)
2)url_matches 网页网址是否匹配特定内容
#url是https://www.baidu.com/
pattern = r’/(\w+)

标签:05,Python,Selenium,元素,driver,EC,element,located,locator
From: https://blog.51cto.com/u_1439909/6321643

相关文章

  • Python 1-11 练习一
    Python1-11练习一一、已知字符串s=“aAsmr3idd4bgs7Dlsf9eAF”,要求如下1、请将s字符串的大写改为小写,小写改为大写。#使用字符串的内置方法a.swapcase():s='aAsmr3idd4bgs7Dlsf9eAF't=s.swapcase()print(t)2、请将s字符串的数字取出,并输出成一个新的字符串。s=......
  • Python 1-10 字符串操作
    Python1-10字符串操作1、字符串拼接>>>s='hello'*2>>>s='hello'+'world'>>>s='hello''world'>>>......
  • Python 02 Xpath
    XpathXpath(XMLPathLanguage)是在XML文档中选择节点的语言一、XPath路径表达式1、XPath节点在XPath中,有七种类型的节点:元素、属性、文本、命名空间、处理指令、注释以及文档(根)节点。XML文档是被作为节点树来对待的,树的根被称为文档节点或者根节点。2、XPath节点关系父(Pa......
  • Selenium 007 API
    SeleniumAPIfromseleniumimportwebdriverfromselenium.webdriver.common.byimportByfromselenium.webdriver.support.uiimportWebDriverWaitfromselenium.webdriver.supportimportexpected_conditionsasECdriver=webdriver.Chrome()driver.maximize_w......
  • Python 1-09 字符串
    Python1-09字符串一、Python字符串在Python3中,字符串是由Unicode码点组成的不可变序列。x="Python"y=x+"Cat"xisy#False字符串是用单引号"或双引号""括起来的一串字符,使用三引号创建多行字符串。在Python中单字符也是用字符串表示。>>>var1='HelloWor......
  • 05-译码器
    1.译码器译码器是编码的逆过程,在编码时,每一种二进制代码都赋予了特定的含义,即都代表了一个确定的信号或者是对象;把代码状态的特定含义翻译出来的过程叫做译码,实现译码操作的电路称为译码器,或者说,译码器可以将输入二机制代码的状态翻译成输出信号,以表示其原来含义的电路......
  • 1105. 模型基础
    一、Django的ORM简介1.ORM系统概念:对象关系映射(ObjectRelationalMapping,简称ORM)优势:不用直接编写SQL代码,只需像操作对象一样从数据库操作数据。2.django模型映射关系①模型类必须都写在app下的modles.py文件中②模型如果需要映射到数据库,所在的app必须被安装③一个......
  • python随机爬取五个电影演员一生生涯中出演的电影名称
    为了随机爬取电影演员的电影,需要使用Python中的网络爬虫技术和相关的第三方库,如requests和BeautifulSoup。以下是一个简单的示例程序:importrandomimportrequestsfrombs4importBeautifulSoup#输入要爬取的演员的姓名actor_name=input('请输入要爬取的演员的姓名:')#......
  • 5-19|记录Python调用salt代码
    #放大一importsalt.clientlocal=salt.client.LocalClient()res=local.cmd(f'{minion_id}','test.ping',timeout=10)#方法二importsalt.configimportsalt.loader__opts__=salt.config.minion_config('/etc/salt/minion')__grains__......
  • Python 什么是数组?
    在Python中,数组通常是指用于表示具有相同数据类型的多个元素的数据结构。在Python中,数组可以表示为列表或NumPy数组。列表:Python中最常用的数组表示法是“列表”。一个列表是由一系列有序元素的集合组成,每个元素可以是字符串、数字、布尔值和其他任何类型的对象。例如: ......