2016-03-07 138 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

相關問題