小智 130
您还可以使用以下代码检查pageloaded
IWait<IWebDriver> wait = new OpenQA.Selenium.Support.UI.WebDriverWait(driver, TimeSpan.FromSeconds(30.00));
wait.Until(driver1 => ((IJavaScriptExecutor)driver).ExecuteScript("return document.readyState").Equals("complete"));
Run Code Online (Sandbox Code Playgroud)
Art*_*tem 87
另见这里
你可以期待展示一些元素.像C#中的东西:
WebDriver _driver = new WebDriver();
WebDriverWait _wait = new WebDriverWait(_driver, new TimeSpan(0, 1, 0));
_wait.Until(d => d.FindElement(By.Id("Id_Your_UIElement"));
Run Code Online (Sandbox Code Playgroud)
Sam*_*Sam 35
如果设置驱动程序的隐式等待,然后findElement
在预期在加载页面上的元素上调用该方法,则WebDriver将轮询该元素,直到找到该元素或达到超时值.
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
Run Code Online (Sandbox Code Playgroud)
来源:隐式等待
Pau*_*eld 34
通常,使用Selenium 2.0时,Web驱动程序只应在确定页面已加载后才将控制权返回给调用代码.如果没有,您可以调用waitforelemement
,循环调用findelement
直到找到或超时(可以设置超时).
all*_*kim 21
Ruby实现:
wait = Selenium::WebDriver::Wait.new(:timeout => 10)
wait.until {
@driver.execute_script("return document.readyState;") == "complete"
}
Run Code Online (Sandbox Code Playgroud)
小智 17
你可以删除该System.out
行.它是为了调试目的而添加的.
WebDriver driver_;
public void waitForPageLoad() {
Wait<WebDriver> wait = new WebDriverWait(driver_, 30);
wait.until(new Function<WebDriver, Boolean>() {
public Boolean apply(WebDriver driver) {
System.out.println("Current Window State : "
+ String.valueOf(((JavascriptExecutor) driver).executeScript("return document.readyState")));
return String
.valueOf(((JavascriptExecutor) driver).executeScript("return document.readyState"))
.equals("complete");
}
});
}
Run Code Online (Sandbox Code Playgroud)
hwj*_*wjp 13
所有这些解决方案都适用于特定情况,但它们至少会遇到以下几个问题:
它们不够通用 - 它们希望您提前知道某些特定条件对于您要访问的页面是否正确(例如,将显示某个元素)
它们对竞争条件持开放态度,您可以使用旧页面上实际存在的元素以及新页面.
这是我尝试避免这个问题的通用解决方案(在Python中):
首先,一个通用的"等待"函数(如果你愿意,可以使用WebDriverWait,我发现它们很难看):
def wait_for(condition_function):
start_time = time.time()
while time.time() < start_time + 3:
if condition_function():
return True
else:
time.sleep(0.1)
raise Exception('Timeout waiting for {}'.format(condition_function.__name__))
Run Code Online (Sandbox Code Playgroud)
接下来,该解决方案依赖于selenium为页面上的所有元素(包括顶级元素)记录(内部)id号的事实<html>
.当页面刷新或加载时,它会获得一个带有新ID的新html元素.
因此,假设您要单击带有文本"我的链接"的链接,例如:
old_page = browser.find_element_by_tag_name('html')
browser.find_element_by_link_text('my link').click()
def page_has_loaded():
new_page = browser.find_element_by_tag_name('html')
return new_page.id != old_page.id
wait_for(page_has_loaded)
Run Code Online (Sandbox Code Playgroud)
对于更多Pythonic,可重用的通用助手,您可以创建一个上下文管理器:
from contextlib import contextmanager
@contextmanager
def wait_for_page_load(browser):
old_page = browser.find_element_by_tag_name('html')
yield
def page_has_loaded():
new_page = browser.find_element_by_tag_name('html')
return new_page.id != old_page.id
wait_for(page_has_loaded)
Run Code Online (Sandbox Code Playgroud)
然后你可以在任何硒交互中使用它:
with wait_for_page_load(browser):
browser.find_element_by_link_text('my link').click()
Run Code Online (Sandbox Code Playgroud)
我认为那是防弹的!你怎么看?
小智 11
您还可以使用类:ExpectedConditions
显式等待元素显示在网页上,然后才能采取任何操作进一步操作
您可以使用ExpectedConditions
该类来确定元素是否可见:
WebElement element = (new WebDriverWait(getDriver(), 10)).until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("input#houseName")));
Run Code Online (Sandbox Code Playgroud)
有关ExpectedConditions class Javadoc
您可以检查的所有条件的列表,请参阅.
小智 10
Imran的回答重新针对Java 7:
WebDriverWait wait = new WebDriverWait(driver, 30);
wait.until(new ExpectedCondition<Boolean>() {
public Boolean apply(WebDriver wdriver) {
return ((JavascriptExecutor) driver).executeScript(
"return document.readyState"
).equals("complete");
}
});
Run Code Online (Sandbox Code Playgroud)
小智 10
这是当前最受好评的答案的 Java 8 版本:
WebDriverWait wait = new WebDriverWait(myDriver, 15);
wait.until(webDriver -> ((JavascriptExecutor) myDriver).executeScript("return document.readyState").toString().equals("complete"));
Run Code Online (Sandbox Code Playgroud)
当myDriver
一个WebDriver
对象(早些时候宣布)。
注意:请注意,此方法 ( document.readyState
) 仅检查 DOM。
如果要等待加载特定元素,可以使用以下isDisplayed()
方法RenderedWebElement
:
// Sleep until the div we want is visible or 5 seconds is over
long end = System.currentTimeMillis() + 5000;
while (System.currentTimeMillis() < end) {
// Browsers which render content (such as Firefox and IE) return "RenderedWebElements"
RenderedWebElement resultsDiv = (RenderedWebElement) driver.findElement(By.className("gac_m"));
// If results have been returned, the results are displayed in a drop down.
if (resultsDiv.isDisplayed()) {
break;
}
}
Run Code Online (Sandbox Code Playgroud)
(5分钟入门指南中的示例)
这似乎是WebDriver的严重限制.显然等待一个元素并不意味着页面被加载,特别是DOM可以完全构建(onready状态),JS仍在执行,CSS和图像仍在加载.
我相信最简单的解决方案是在初始化所有内容后在onload事件上设置一个JS变量,然后在Selenium中检查并等待这个JS变量.
在此等待中明确等待或有条件等待,直到给出此条件.
WebDriverWait wait = new WebDriverWait(wb, 60);
wait.until(ExpectedConditions.elementToBeClickable(By.name("value")));
Run Code Online (Sandbox Code Playgroud)
这将等待每个web元素60秒.
隐式使用等待页面上每个元素的等待直到给定时间.
driver.manage().timeouts().implicitlyWait(60, TimeUnit.SECONDS);
Run Code Online (Sandbox Code Playgroud)
这将等待每个web元素60秒.
男人所有这些答案都需要太多的代码。这应该是一件简单的事情,因为它很常见。
为什么不直接在 webdriver 中注入一些简单的 Javascript 并检查。这是我在 webscraper 类中使用的方法。Javascript 是非常基础的,即使你不知道。
def js_get_page_state(self):
"""
Javascript for getting document.readyState
:return: Pages state.
More Info: https://developer.mozilla.org/en-US/docs/Web/API/Document/readyState
"""
ready_state = self.driver.execute_script('return document.readyState')
if ready_state == 'loading':
self.logger.info("Loading Page...")
elif ready_state == 'interactive':
self.logger.info("Page is interactive")
elif ready_state == 'complete':
self.logger.info("The page is fully loaded!")
return ready_state
Run Code Online (Sandbox Code Playgroud)
小智 5
I'm surprised that predicates weren't the first choice as you typically know what element(s) you will next interact with on the page you're waiting to load. My approach has always been to build out predicates/functions like waitForElementByID(String id)
and waitForElemetVisibleByClass(String className)
, etc. and then use and reuse these wherever I need them, be it for a page load or page content change I'm waiting on.
For example,
In my test class:
driverWait.until(textIsPresent("expectedText");
Run Code Online (Sandbox Code Playgroud)
In my test class parent:
protected Predicate<WebDriver> textIsPresent(String text){
final String t = text;
return new Predicate<WebDriver>(){
public boolean apply(WebDriver driver){
return isTextPresent(t);
}
};
}
protected boolean isTextPresent(String text){
return driver.getPageSource().contains(text);
}
Run Code Online (Sandbox Code Playgroud)
Though this seems like a lot, it takes care of checking repeatedly for you and the interval for how often to check can be set along with the ultimate wait time before timing out. Also, you will reuse such methods.
在这个例子中,父类定义并启动了WebDriver driver
和WebDriverWait driverWait
.
我希望这有帮助。
小智 5
使用隐式等待页面上每个元素的等待直到给定的时间。
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
Run Code Online (Sandbox Code Playgroud)
这将等待页面上的每个元素30秒。
另一个等待是显式等待或条件等待,在此等待中直到给定条件。
WebDriverWait wait = new WebDriverWait(driver, 40);
WebElement element = wait.until(ExpectedConditions.elementToBeClickable(By.id("someid")));
Run Code Online (Sandbox Code Playgroud)
在id中,请提供静态元素ID,该ID会在页面加载后立即显示在页面上。
归档时间: |
|
查看次数: |
393527 次 |
最近记录: |