2016-03-07 82 views
1

我想要做一些基本的网页爬行,并希望能够接受(或关闭)屏幕上的任何警报,以便我可以访问页面元素。此前,我是通过预期等待警报来管理这个问题的。在接受警报之前等待页面加载Selenium Webdriver

private void handleAlert(){ 
    try{ 
     WebDriverWait wait = new WebDriverWait(driver, 2); 
     wait.until(ExpectedConditions.alertIsPresent()); 
     Alert alert = driver.switchTo().alert(); 
     alert.accept(); 
     Logger.log("Accepting alert~!~~~~!!!"); 
     }catch(NoAlertPresentException e){ 
      // Do nothing :D 
     }catch(UnhandledAlertException e){ 
       Logger.writeError("An alert was not handled!"); 
     }catch(TimeoutException e){ 
      Logger.writeError("There was a timeout occurring handling alert"); 
     } 
    } 
} 

但是,这个问题,如果一个页面没有在最初2秒加载,但随后的负载之后(我的页面加载超时为15秒)。在这种情况下,出现警报,但我不会再试图解雇/接受此问题。

为了解决这个问题,我决定写一些代码,等待页面加载后再尝试处理警报。代码如下:

/** 
    * Load an Url in the chrome browser via Selenium driver 
    * @param url: The web address to be crawled 
    * @throws InterruptedException 
    */ 
    public boolean loadUrl(String url) throws InterruptedException{ 
     try{ 
      driver.get(url); 
      waitTillPageLoads(); 
      handleAlert(); 
      return true; 
     }catch(TimeoutException e){ 
      //e.printStackTrace(); 
      Logger.writeError("There was a timeout for the url: "+url); 
      return false; 
     } 
    } 

    /** 
    * Use webdriver expected conditions override to wait until 
    * DOM state is completed 
    */ 
    private void waitTillPageLoads(){ 
     ExpectedCondition<Boolean> expectation = new ExpectedCondition<Boolean>() 
      { 
       public Boolean apply(WebDriver driver) 
       { 
        return ((JavascriptExecutor)driver).executeScript("return document.readyState").equals("complete"); 
       } 
      }; 
     Wait<WebDriver> wait = new WebDriverWait(driver,30); 
     wait.until(expectation); 
    } 

Buuuuut,如果我这样做,我得到一个AlertNotHandledException由下面的总结堆栈跟踪指定:

Exception in thread "main" org.openqa.selenium.UnhandledAlertException: unexpected alert open 
    Session ID: 876c48f2d94d10fe30984ab94f32884e 
     at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) 
     at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) 
     at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) 
     at java.lang.reflect.Constructor.newInstance(Constructor.java:408) 
     at org.openqa.selenium.remote.ErrorHandler.createThrowable(ErrorHandler.java:206) 
     at org.openqa.selenium.remote.ErrorHandler.throwIfResponseFailed(ErrorHandler.java:164) 
     at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:678) 
     at org.openqa.selenium.remote.RemoteWebDriver.executeScript(RemoteWebDriver.java:577) 
     at src.com.chrome.TestChromeDriver$1.apply(TestChromeDriver.java:349) 
     at src.com.chrome.TestChromeDriver$1.apply(TestChromeDriver.java:1) 
     at org.openqa.selenium.support.ui.FluentWait.until(FluentWait.java:238) 
     at src.com.chrome.TestChromeDriver.waitTillPageLoads(TestChromeDriver.java:353) 
     at src.com.chrome.TestChromeDriver.loadUrl(TestChromeDriver.java:364) 
     at src.com.chrome.TestChromeDriver.crawl(TestChromeDriver.java:308) 
     at src.com.chrome.TestChromeDriver.main(TestChromeDriver.java:132) 

所以,我怎么等到页面加载然后尝试处理一个JavaScript警告,如果它存在。谢谢!

回答

0

如果你知道你在做什么,并真的必须绕过所有JavaScript警告和对话框不顾后果,你总是可以follow this advice

((JavascriptExecutor) driver).executeScript("window.alert = function() {}; window.prompt = function() {return null}; window.confirm = function() {return true}");

您将需要运行在后每页面加载,但它肯定比尝试处理不可预知的变量行为更清洁。

(如果你想试用它,打开浏览器的开发者工具,粘贴小脚本在JS控制台,然后验证alert('hi');什么都不做。)

+0

我只是尝试这样做(由基本取代我的handleAlert函数与你的片段),并且它返回一个UnhandledAlertException xD。我发现这很有趣,因为这正是应该避免哈哈哈。 – varunforthehills

+0

我看不到您要加载的页面,并且无法知道这些警报应该发生在哪里,但是如果您在执行页面之前加载页面,那可能为时已晚。在您请求页面之后,您应该尽快运行它,以尽量减少显示任何警报/对话的机会。 –

+0

我会试试这个,并回报,谢谢! – varunforthehills

相关问题