是否有比Thread.Sleep()更好的Sleep()方法?
问题描述
假设我正在尝试查找名为element0
的元素,
driver.FindElement(element0).Click;
Thread.Sleep(5000);
根据我的WiFi速度,element0
可能需要花费5000到10000毫秒才能显示。
必须不断更改Thread.Sleep()
中的值会破坏自动化的目的。
围绕try catch块周围可以工作:
try
{
driver.FindElement(element0).Click;
Thread.Sleep(5000);
}
catch(org.openqa.selenium.NoSuchElementException e)
{
driver.FindElement(element0).Click;
Thread.Sleep(5000);
}
但是如果在捕获element0
之后仍然不存在org.openqa.selenium.NoSuchElementException e
,那么它只会抛出另一个相同的错误。
有没有更好的方法让我的代码进入睡眠状态?
我是否可以循环循环遍历driver.FindElement(element0).Click
直到element0
存在?
思路一:
硒气体明确用于该目的
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
WebDriverWait wait = new WebDriverWait(WebDriverRefrence, 10);
WebElement element = wait.until(ExpectedConditions.visibilityOfElementLocated(element0));
element.click();
这将等待up至10秒钟,以使元素可见。您还有很多ExpectedConditions可以选择。
思路二:
在findElement之后也使用睡眠将导致无意义的暂停,因为findElemen将使用定义的超时https://www.selenium.dev/selenium/docs/api/java/org/openqa/selenium/WebDriver.Timeouts.html
您可以隐式增加等待元素的超时时间。
driver.manage().timeouts().implicitlyWait(TimeOut, TimeUnit.SECONDS);
思路三:
Thread.Sleep()
Thread.Sleep()
暂停执行将导致当前正在执行的线程在指定时间段内暂停执行。这是使处理器时间可用于应用程序的其他线程或可能在同一系统上运行的其他应用程序的有效方法。但是,这些睡眠时间不能保证精确,因为它们受基础Thread.Sleep()
提供的设施的限制。睡眠时间也可以通过中断来终止。最重要的是,您不能假设调用sleep将在指定的时间段内精确地挂起线程。
implicitlylyWait
使用os时,可以将Selenium替换为sleep。通过诱使implicitlyWait,driver实例将轮询implicitlyWait,直到在配置的时间内找到元素为止,然后在抛出DOM Tree之前查找一个或多个元素。
-
示例:
-
Python:
NoSuchElementException
-
Java:
driver.implicitly_wait(10)
-
DotNet:
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
-
ExplicitWait
但是,更好的方法是将[[sleep替换为driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(10);
,该配置将驱动程序实例配置为在继续下一行代码之前等待特定条件得到满足。
- 示例:
-
Python:
ExplicitWait
-
-
Java:
WebDriverWait(driver, 20).until(EC.presence_of_element_located((By.CSS_SELECTOR, "element_css")))
DotNet:
new WebDriverWait(driver, 20).until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("element_css")));