显式等待Python3中存在的元素

时间:2018-04-19 14:57:03

标签: python python-3.x selenium-webdriver

我正在尝试使用显式等待selenium webdriver但是几天后我的尝试都没有成功。 我多次阅读http://selenium-python.readthedocs.io/waits.html#explicit-waits,但这对我没有帮助。

这是代码的最新版本,我收到错误:

#-----step1
change_element = driver.find_element_by_xpath("//img [@ title= 'settings']").click()  
#-----wait
try:
    change_element = WebDriverWait(driver,10).until(EC.presence_of_element_located((By.XPATH,"//input [@ id= 'NAME']"))) 
#Error: selenium.common.exceptions.NoSuchElementException: Message: Unable to locate element: //input [@ id= 'NAME']
except:
    time.sleep(3)
#-----step2
driver.find_element_by_xpath("//input [@ id= 'NAME']").clear() 
#Error: selenium.common.exceptions.NoSuchElementException: Message: Unable to locate element: //input [@ id= 'NAME']    
input_element = driver.find_element_by_xpath("//input [@ id= 'NAME']")
input_element.send_keys(v[1])

但如果我使用下面的代码,则没有错误:

change_element = driver.find_element_by_xpath("//img [@ title= 'settings']").click()
time.sleep(25)
driver.find_element_by_xpath("//input [@ id= 'NAME']").clear()
input_element_FIO = driver.find_element_by_xpath("//input [@ id= 'NAME']")
input_element_FIO.send_keys(v[1])

我在结构中的错误“尝试除了”但我不明白如何使用下面的算法编写它:

1 I want to wait for the download of the item @ id= 'NAME' each 10 sec, then execute  driver.find_element_by_xpath("//input [@ id= 'NAME']").clear()
2 if the element  @ id= 'NAME' not loaded then wait 3 sec
3 if an item is loaded @ id= 'NAME' then execute driver.find_element_by_xpath("//input [@ id= 'NAME']").clear()
4 if the element @ id= 'NAME' not loaded then wait again 10 sec , then execute  driver.find_element_by_xpath("//input [@ id= 'NAME']").clear()

有人可以帮助我吗?

1 个答案:

答案 0 :(得分:1)

因此,让我们考虑一下所有这些代码和重新编写的内容。

1 I want to wait for the download of the item @ id= 'NAME' each 10 sec, then execute  driver.find_element_by_xpath("//input [@ id= 'NAME']").clear()
2 if the element  @ id= 'NAME' not loaded then wait 3 sec
3 if an item is loaded @ id= 'NAME' then execute driver.find_element_by_xpath("//input [@ id= 'NAME']").clear()
4 if the element @ id= 'NAME' not loaded then wait again 10 sec , then execute  driver.find_element_by_xpath("//input [@ id= 'NAME']").clear()

这可以分解为一个陈述

I want to wait until the element is there before I interact with it

您可以通过导入和使用WebDriverWait来完成此操作。

WebDriverWait上的第二个参数告诉WebDriver在几秒钟内继续尝试找到此元素。在此期间,它将每隔几百毫秒尝试定位元素。如果在没有WebDriver找到元素的情况下经过了这个定义的时间,它将引发TimeoutException并且您的脚本将退出。

我认为您不想捕获此异常,因为如果您在此时找不到您正在寻找的元素,则您的测试可能处于错误状态。

以下是WebDriver培训网站上的一个示例,其中显示了用法:

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import time

path = 'C:/Users/will/Downloads/chromedriver1/chromedriver.exe'
driver = webdriver.Chrome(path)

time.sleep(5)

driver.get("http://the-internet.herokuapp.com/dynamic_loading/1")

driver.find_element_by_xpath("//button[text()='Start']").click()

hwElem = WebDriverWait(driver, 30).until(EC.visibility_of_element_located((By.XPATH, "//h4[text()='Hello World!']")))

print(hwElem.text)

driver.quit()

如果你在以上述方式使用WebDriverWait时仍然得到NoSuchElementException(并且你没有捕获异常!)那么我会说你的脚本的不同部分是一个错误,因为它没有办法从以这种方式使用的WebDriverWait.until中抛出该异常。

一些额外的提示:

  • 除非你知道自己在做什么,否则不要抓住你的例外情况,特别是不是全部。这可能非常令人困惑,并导致你走错了路,试图找出错误的原因
  • 由于这似乎是一个动态元素,它可能隐藏在页面上并等待显示,因此请使用EC.visibility_of_element_located以避免与可能存在的项目进行交互,但不可见 < / LI>
  • WebDriverWait.until将处理自己的重试尝试,您不需要多次运行它,如果您知道网站可能不会显示此元素超过25秒,则只需增加超时持续时间。它会检查每200毫秒,我认为是。最多500毫秒。