Selenium-Java-geckodriver:由于“document.getElementById(...)为null”

时间:2017-05-24 12:20:56

标签: javascript java selenium getelementbyid selenium-firefoxdriver

我现在已经遇到这个问题了一段时间。在SO&上浏览了大量的主题其他论坛,但仍然无能为力。

使用Selenium 3.4.0,geckodriver v0.16.1& amp; Eclipse Neon v2 IDE中的Mozilla Firefox 53.0,我在控制台上间歇性地遇到错误:

JavaScript error: https://www.url.com/my, line 1715: TypeError: document.getElementById(...) is null

虽然使用chromedriver v2.29 / Google Chrome 58.0或使用Python,但我不会遇到任何此类问题。

出现此错误后,测试执行停止并最终显示TimeoutException,如下所示:

Exception in thread "main" org.openqa.selenium.TimeoutException: Timeout loading page after 300000ms

网站的网址为:https://www.shareinvestor.com/my

HTML DOM是:

<div id="sic_sitemap">
  <div id="sic_container">
    <div id="sic_header">
      <h1 id="sic_siteTitle">
        <div id="sic_headerMembershipLink">
          <a id="sic_mobileEdition" href="/mobile">
            <div id="sic_loginContainer" class="sic_logIn" style="">
              <div class="sic_login-wrap">
                <div class="sic_logIn-subscribe">
                  <div class="sic_logIn-bg">
                    <a href="/user/login.html">
                  </div>
                </div>
              </div>
            </div>
            <div id="sic_subHeader">
              <div id="sic_mainNav" class="sic_withRightCorner">
                <div id="sic_sideBar" class="sic_expanded { selected_market_suffix: 'MY'}">
                  <div class="sic_superBanner sic_superBannerTop">
                    <div id="sic_content" class="sic_collapsed">
                      <div id="sic_footer" class="si_fixed">
                      </div>

截至目前,我已经尝试了以下选项但无济于事:

  1. Java Click
  2. JavascriptExecutor点击
  3. 操作点击
  4. 这是我的代码:

    import org.openqa.selenium.By;
    import org.openqa.selenium.JavascriptExecutor;
    import org.openqa.selenium.WebDriver;
    import org.openqa.selenium.WebElement;
    import org.openqa.selenium.firefox.FirefoxDriver;
    import org.openqa.selenium.interactions.Actions;
    import org.openqa.selenium.remote.DesiredCapabilities;
    
    public class 78644072022 {
    
    public static void main(String[] args) {
    
        System.setProperty("webdriver.gecko.driver", "C:\\Utility\\BrowserDrivers\\geckodriver.exe");
        DesiredCapabilities dc = DesiredCapabilities.firefox();
        dc.setCapability("marionette", true);
        WebDriver driver =  new FirefoxDriver(dc);
        driver.manage().window().maximize();
        driver.get("https://www.shareinvestor.com/my");
        WebElement login_button = driver.findElement(By.xpath("//div[@id='sic_loginContainer']/div/div[@class='sic_logIn-bg']/a"));
    
        //Java Click
        login_button.click();
    
        //JavascriptExecutor Click
        /*JavascriptExecutor jse = (JavascriptExecutor)driver;
        jse.executeScript("arguments[0].click();", login_button);*/
    
        //Actions Click
        /*Actions act = new Actions(driver);
        act.moveToElement(login_button).click().build().perform();*/
    
        driver.findElement(By.xpath("//input[@id='sic_login_header_username']")).sendKeys("debanjan");
        driver.findElement(By.xpath("//input[@id='sic_login_header_password']")).sendKeys("5786");
        driver.findElement(By.xpath("//input[@id='sic_login_submit']")).click();
    }
    }
    

    我正在寻找带有geckodriver的Java解决方案来克服错误JavaScript error:TypeError: document.getElementById(...) is null

    在其中一个SO threads中,我看到了一个解决方案:

      

    您需要在updateHTML中执行null检查,如下所示:

    function updateHTML(elmId, value) {
      var elem = document.getElementById(elmId);
      if(typeof elem !== 'undefined' && elem !== null) {
        document.getElementById(elmId).innerHTML = value;
      }
    }
    

    我们可以实现吗? 任何建议&amp;指针会有所帮助。

5 个答案:

答案 0 :(得分:1)

  

我正在寻找带有geckodriver的Java解决方案来克服错误JavaScript错误:TypeError:document.getElementById(...)为null

要回答你的问题,我不相信你可以采取任何措施来修复&#34;这是通过Java / Selenium。这是一个JavaScript错误,它源自您尝试访问的网站。您可能需要考虑contacting他们的支持团队,也许他们的开发人员可以查看此问题。

不是点击登录按钮,而是考虑直接导航到登录页面?

driver.get("https://www.shareinvestor.com/user/login.html");

答案 1 :(得分:1)

首先,由于任何selenium代码都没有触发那些javascript错误。当然,超时是由硒引发的(将在稍后讨论)。

无论您使用何种浏览器启动网址,都会收到该javascript错误。但是在gecko的情况下,你会在eclipse控制台中收到通知,但不是Chrome。如果你需要在chrome中看到java脚本错误,只需在chrome中启动url并转到devtools / console(F12)。您也可以在firefox控制台中看到相同的内容。

  • Chrome Img:

Error shown in Chrome console

其次,我们遇到超时异常,因为该网站实际上需要花费太多时间才能加载。我等了7分钟,即使现在页面仍在加载。除非页面已完全启动,否则Selenium不会执行其脚本。因此,我们将获得超时异常(不确定允许的默认页面启动时间)。我想过直接绕过登录页面(&#34; https://www.shareinvestor.com/user/login.html&#34;),并且也没有花费任何有限的时间来完全加载。

内插:那些java脚本错误不是自动化的问题但是那些页面加载确实是。对于这个问题,这个网站似乎不是一个很好的自动化候选者。

Update1:​​否则我们也可以通过另一个线程停止页面加载,例如发送&#34; esc&#34;使用Action类的键序列。

Update2:我今天尝试了相同的代码,它运行正常。下面是我尝试过的代码片段(根本没有变化)

 public static void main(String[] args) throws InterruptedException 
{
    System.setProperty("webdriver.gecko.driver", "F:\\Softwares\\Selenium\\Webdriver\\geckodriver.exe");
    WebDriver driver = new FirefoxDriver();
    driver.manage().window().maximize();
    driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS);
    driver.get("https://www.shareinvestor.com/my");
    WebElement login_button = driver.findElement(By.xpath("//div[@id='sic_loginContainer']/div/div[@class='sic_logIn-bg']/a"));

    //Java Click
    login_button.click();
    System.out.println("In Login PAge");

    driver.findElement(By.xpath("//input[@id='sic_login_header_username']")).sendKeys("debanjan");
    driver.findElement(By.xpath("//input[@id='sic_login_header_password']")).sendKeys("5786");
    System.out.println("Entered password");
    driver.findElement(By.xpath("//input[@id='sic_login_submit']")).click();
}

Selenium版本 - 3.4.0

Gecko驱动程序 - v0.16.1(我的是32位)

Mozilla - 51.0.1(更新=&gt;它也在53.02上工作)

希望这会对你有所帮助。感谢。

答案 2 :(得分:0)

我想我已经设法在你的脚本中找到导致这种骚动的原因。 我检查了你的HTML,似乎javascript方法function showRemaining()导致了这个问题;因为showRemaining()包含此声明

    document.getElementById('countdown').innerHTML = '';

它尝试将id为countdown的元素的innerHTML属性设置为''。

但是网页上的任何地方都不存在倒计时错误。

TypeError: document.getElementById(...) is null

以某种方式,selenium无法查看此错误。因此,我认为从开发人员那里修复它应该可以帮到你。

更新:

基本上你需要等待所有元素加载使用隐式等待,一旦加载所有元素,然后你的Javascript错误得到解决,最终与网页的交互不会受到javascript错误的阻碍:

        driver.get("https://www.shareinvestor.com/my");

        driver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);
        driver.manage().window().maximize();

        /*String script = "function updateHTML(countdown, value) {" +
                "var elem = document.getElementById('countdown');"+
                "if(typeof elem !== 'undefined' && elem !== null) {"+
                " document.getElementById('countdown').innerHTML = value;"+
                "}"+
                "}";

        ((JavascriptExecutor) driver).executeScript(script);*/

        WebElement login_button = driver.findElement(By.xpath("//div[@id='sic_loginContainer']/div/div[@class='sic_logIn-bg']/a"));

        login_button.click();

        driver.findElement(By.xpath("//input[@id='sic_login_header_username']")).sendKeys("debanjan");
        driver.findElement(By.xpath("//input[@id='sic_login_header_password']")).sendKeys("5786");
        driver.findElement(By.xpath("//input[@id='sic_login_submit']")).click();

答案 3 :(得分:0)

看起来login_button的XPath不正确:

By.xpath("//div[@id='sic_loginContainer']/div/div[@class='sic_logIn-bg']/a");

应该是:

By.xpath("//div[@id='sic_loginContainer']/div/div/div[@class='sic_logIn-bg']/a");

这可以解释TimeoutException,因为Selenium无法找到不存在的元素。编辑:我的错误,如果元素不能,你应该看到NoSuchElementException位于。

对于JavaScript错误,除非您尝试使用Selenium访问由JavaScript代码(id='countdown'元素)操纵的Web元素,否则Selenium应该忽略该错误。否则,可能存在其他Selenium错误,例如StaleElementReferenceException,但情况似乎并非如此。

答案 4 :(得分:0)

这是由于您的应用程序HTML页面使用异步javascript,它使用了一些在执行时不可用的变量引用。我们遇到了同样的问题,并要求开发人员在HTML中遵循javascript的一些最佳实践,例如将脚本标记放在页面末尾。我检查了网站的HTML页面源,它​​在代码之间包含许多脚本标记。这将阻止DOM渲染。更好的是,请开发人员遵循一些最佳实践,在HTML中包含脚本标记。您可以参考链接Where should I put <script> tags in HTML markup?获取最佳做法。