【问题标题】:NoSuchElementException, Selenium unable to locate elementNoSuchElementException,Selenium 无法定位元素
【发布时间】:2018-07-06 09:09:05
【问题描述】:

我想在 selenium 中找到我的 TextField,但我不知道如何(我第一次使用 sellenium)。

我试过了:

 driver.findElement(By.id("originTextField"))

或者通过开发工具中chrome生成的xPath和cssSelector String。

请帮助我,我将不胜感激。

这是html:

【问题讨论】:

    标签: selenium selenium-webdriver css-selectors webdriver selenium-chromedriver


    【解决方案1】:

    NoSuchElementException

    org.openqa.selenium.NoSuchElementException 俗称 NoSuchElementException 扩展 org.openqa.selenium.NotFoundException,这是 WebDriverException 的一种类型。

    NoSuchElementException 可以在以下两种情况下抛出:

    • 使用WebDriver.findElement(By by)时:

      //example : WebElement my_element = driver.findElement(By.xpath("//my_xpath"));
      
    • 使用WebElement.findElement(By by)时:

      //example : WebElement my_element = element.findElement(By.xpath("//my_xpath"));
      

    根据 JavaDocs,就像任何其他 WebDriverException 一样,NoSuchElementException 应该包含以下 常量字段

    Constant Field      Type                                        Value
    SESSION_ID          public static final java.lang.String        "Session ID"
    e.g. (Session info: chrome=63.0.3239.108)
    
    DRIVER_INFO         public static final java.lang.String        "Driver info"
    e.g. (Driver info: chromedriver=2.34.522940 (1a76f96f66e3ca7b8e57d503b4dd3bccfba87af1),platform=Windows NT 6.1.7601 SP1 x86)
    
    BASE_SUPPORT_URL    protected static final java.lang.String     "http://seleniumhq.org/exceptions/"
    e.g. (For documentation on this error, please visit: http://seleniumhq.org/exceptions/no_such_element.html)
    

    原因

    NoSuchElementException 的原因可能是以下之一:

    • 您采用的定位器策略没有识别HTML DOM中的任何元素。
    • 您采用的定位器策略无法识别该元素,因为它不在浏览器的Viewport 中。
    • 您采用的 Locator Strategy 标识了元素,但由于存在属性 style="display: none;" 而不可见。
    • 您采用的 Locator Strategy 不能唯一地 识别 HTML DOM 中的所需元素,目前还可以找到其他一些 隐藏 / 不可见 元素。
    • 您尝试定位的 WebElement 位于 <iframe> 标记内。
    • WebDriver 实例甚至在 HTML DOM 中存在/可见元素之前就开始寻找 WebElement

    解决方案

    解决NoSuchElementException的解决方案可以是以下任何一种:

    • 采用一个Locator Strategy 唯一标识所需的WebElement。您可以借助开发者工具 (Ctrl+Shift+IF12) 并使用元素检查器

      这里有关于how to inspect element in selenium3.6 as firebug is not an option any more for FF 56?的详细讨论

    • 使用executeScript()方法滚动元素查看如下:

      WebElement elem = driver.findElement(By.xpath("element_xpath"));
      ((JavascriptExecutor)driver).executeScript("arguments[0].scrollIntoView();", elem);
      

      这里有关于Scrolling to top of the page in Python using Selenium的详细讨论

    • Incase 元素具有 style="display: none;" 属性,通过executeScript() 方法删除该属性,如下所示:

      WebElement element = driver.findElement(By.xpath("element_xpath"));
      ((JavascriptExecutor)driver).executeScript("arguments[0].removeAttribute('style')", element)
      element.sendKeys("text_to_send");
      
    • 要检查元素是否在<iframe> 内,遍历HTML 以通过以下任一方式定位相应的<iframe> 标记和switchTo() 所需的iframe以下方法:

      driver.switchTo().frame("frame_name");
      driver.switchTo().frame("frame_id");
      driver.switchTo().frame(1); // 1 represents frame index
      

      在这里你可以找到关于Is it possible to switch to an element in a frame without using driver.switchTo().frame(“frameName”) in Selenium Webdriver Java?的详细讨论。

    • 如果元素在 HTML DOM 中不存在/可见,则将WebDriverWaitExpectedConditions 设置为正确的方法如下:

      • 等待presenceOfElementLocated

        new WebDriverWait(driver, 20).until(ExpectedConditions.presenceOfElementLocated(By.xpath("//div[@class='buttonStyle']//input[@id='originTextField']")));
        
      • 等待visibilityOfElementLocated

        new WebDriverWait(driver, 20).until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//div[@class='buttonStyle']//input[@id='originTextField']")));
        
      • 等待elementToBeClickable

        new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.xpath("//div[@class='buttonStyle']//input[@id='originTextField']")));
        

    参考

    您可以在以下位置找到Selenium 客户端相关讨论:

    【讨论】:

    • 感谢您的回答,能否为executeScript() 方法提供python 的等效项?谢谢!
    【解决方案2】:

    您的代码是正确的,我怀疑该问题导致您找到该元素时页面未完全加载。

    尝试在查找元素之前添加长时间睡眠,如果添加睡眠有效,则将睡眠更改为等待。

    代码如下,如果元素不存在则等待10s:

    element = WebDriverWait(driver, 10).until(
        EC.presence_of_element_located((By.ID, "originTextField"))
    )
    

    【讨论】:

    • 或者你可以输入sleep(1000);然后driver.findElement(By.id("originTextField"))
    【解决方案3】:

    以下代码将帮助您解决问题

    wait = new WebDriverWait(driver, 60);
    wait.until(ExpectedConditions.presenceOfElementLocated(By.id("originTextField")));
    

    wait = new WebDriverWait(driver, 90);
    wait.until(ExpectedConditions.visibilityOf(element)).wait(20);
    

    【讨论】:

      猜你喜欢
      • 2019-11-25
      • 2018-07-12
      • 2019-08-08
      • 2022-01-06
      相关资源
      最近更新 更多