如何让Selenium 2.0等待页面加载?
当前回答
NodeJS答案:
在Nodejs中,你可以通过承诺得到它…
如果您编写了这段代码,您可以确保当您到达then…
driver.get('www.sidanmor.com').then(()=> {
// here the page is fully loaded!!!
// do your stuff...
}).catch(console.log.bind(console));
如果您编写了这段代码,您将进行导航,selenium将等待3秒……
driver.get('www.sidanmor.com');
driver.sleep(3000);
// you can't be sure that the page is fully loaded!!!
// do your stuff... hope it will be OK...
来自Selenium Documentation (Nodejs):
这一点。get(url)→Thenable<undefined> 调度命令导航到给定的URL。 返回一个承诺,该承诺将在文档完成加载时得到解决。
其他回答
所有这些解决方案在特定情况下都是可行的,但它们至少会遇到以下几个问题中的一个:
它们不够通用——它们想让你提前知道,你要访问的页面的某些特定条件将是真的(例如某些元素将被显示)。 它们会出现竞态条件,即您使用的元素实际上同时出现在旧页面和新页面上。
下面是我尝试的避免这个问题的通用解决方案(在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__))
接下来,解决方案依赖于这样一个事实,即selenium为页面上的所有元素记录了一个(内部的)id-number,包括顶级的<html>元素。当页面刷新或加载时,它会获得一个带有新ID的新html元素。
假设你想点击一个文本为“my link”的链接,例如:
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)
对于更多python化的、可重用的、通用的helper,你可以创建一个上下文管理器:
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)
然后你可以在几乎任何硒相互作用中使用它:
with wait_for_page_load(browser):
browser.find_element_by_link_text('my link').click()
我想那是防弹的!你怎么看?
更多信息在这里关于它的博客文章
使用这个函数
public void waitForPageLoad(ChromeDriver d){
String s="";
while(!s.equals("complete")){
s=(String) d.executeScript("return document.readyState");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
我使用node + selenium-webdriver(现在的版本是3.5.0)。我所做的是:
var webdriver = require('selenium-webdriver'),
driver = new webdriver.Builder().forBrowser('chrome').build();
;
driver.wait(driver.executeScript("return document.readyState").then(state => {
return state === 'complete';
}))
public static int counter = 0;
public void stepGeneralWait() {
boolean breakIt = true;
while (true) {
breakIt = true;
try {
do{
// here put e.g. your spinner ID
Controller.driver.findElement(By.xpath("//*[@id='static']/div[8]/img")).click();
Thread.sleep(10000);
counter++;
if (counter > 3){
breakIt = false;
}
}
while (breakIt);
} catch (Exception e) {
if (e.getMessage().contains("element is not attached")) {
breakIt = false;
}
}
if (breakIt) {
break;
}
}
try {
Thread.sleep(12000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
SeleniumWaiter:
import com.google.common.base.Function;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.WebDriverWait;
public class SeleniumWaiter {
private WebDriver driver;
public SeleniumWaiter(WebDriver driver) {
this.driver = driver;
}
public WebElement waitForMe(By locatorname, int timeout){
WebDriverWait wait = new WebDriverWait(driver, timeout);
return wait.until(SeleniumWaiter.presenceOfElementLocated(locatorname));
}
public static Function<WebDriver, WebElement> presenceOfElementLocated(final By locator) {
// TODO Auto-generated method stub
return new Function<WebDriver, WebElement>() {
@Override
public WebElement apply(WebDriver driver) {
return driver.findElement(locator);
}
};
}
}
对你来说:
_waiter = new SeleniumWaiter(_driver);
try {
_waiter.waitForMe(By.xpath("//..."), 10);
}
catch (Exception e) {
// Error
}
推荐文章
- 将所有非字母数字字符替换为空字符串
- 漂亮地打印Java集合(toString不返回漂亮输出)
- 静态嵌套类在Java,为什么?
- 如何防止Eclipse在启动时挂起?
- Optional和Optional的区别是什么?flatMap和Optional.map?
- Java中枚举的命名:单数还是复数?
- JavaBean和POJO之间的区别是什么?
- 注释在Java中如何使用,在哪里使用?
- 如何在Ubuntu下安装JDK 11 ?
- Spring Boot -无法确定数据库类型为NONE的嵌入式数据库驱动程序类
- 如何转换/解析从字符串到字符在java?
- 如何在Android中动态更改菜单项文本
- 如何比较两个没有时间部分的日期?
- 如何在Java中找到给定类的所有子类?
- 匿名类的访问构造函数