NoSuchElementExeption,selenium无法定位元素

时间:2018-01-27 00:13:38

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

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

我试过了:

DECLARE @PersonMedication TABLE
  (
     person_nbr      INT NOT NULL,
     [description]   VARCHAR(20) NOT NULL,
     medication_name VARCHAR(50) NOT NULL,
     StartDate       DATE NOT NULL,
     EndDate         DATE NOT NULL
  );

INSERT INTO @PersonMedication
            (person_nbr, [description], medication_name, StartDate, EndDate)
/* End preceeds Start... */
VALUES      (47, 'Intake', 'Seroquel 300 mg tablet', '2017-07-13', '1900-01-01'),
            (47, 'Active', 'Risperdal 1 mg tablet', '2017-10-21', '2017-11-21'),
            (47, 'Active', 'sertraline 100 mg tablet', '2017-10-21', '2017-11-21'),
            (271, 'Active', 'sertraline 100 mg tablet', '2017-11-21', '2017-12-26'),
            (271, 'Active', 'Risperdal 1 mg tablet', '2017-11-21', '2017-12-26');

WITH ctePersonMedicationRowNumber
     AS (SELECT Row_number()
                  OVER (
                    PARTITION BY person_nbr
                    ORDER BY StartDate, EndDate) RowNumber,
                *
         FROM   @PersonMedication)
SELECT tmpPersonMedication1.person_nbr,
       /* Get the most recent description i.e. 5th is older than 4th is older than ... */
       COALESCE(tmpPersonMedication5.[description], tmpPersonMedication4.[description], tmpPersonMedication3.[description], tmpPersonMedication2.[description], tmpPersonMedication1.[description]) [description],
       tmpPersonMedication1.[medication_name]                                                                                                                                                       MedName1,
       tmpPersonMedication1.[StartDate]                                                                                                                                                             MedDate1,
       tmpPersonMedication2.[medication_name]                                                                                                                                                       MedName2,
       tmpPersonMedication2.[StartDate]                                                                                                                                                             MedDate2,
       tmpPersonMedication3.[medication_name]                                                                                                                                                       MedName3,
       tmpPersonMedication3.[StartDate]                                                                                                                                                             MedDate3,
       tmpPersonMedication4.[medication_name]                                                                                                                                                       MedName4,
       tmpPersonMedication4.[StartDate]                                                                                                                                                             MedDate4,
       tmpPersonMedication5.[medication_name]                                                                                                                                                       MedName5,
       tmpPersonMedication5.[StartDate]                                                                                                                                                             MedDate5
FROM   ctePersonMedicationRowNumber tmpPersonMedication1
       LEFT JOIN ctePersonMedicationRowNumber tmpPersonMedication2
              ON tmpPersonMedication1.person_nbr = tmpPersonMedication2.person_nbr
                 AND tmpPersonMedication2.RowNumber = 2
       LEFT JOIN ctePersonMedicationRowNumber tmpPersonMedication3
              ON tmpPersonMedication1.person_nbr = tmpPersonMedication3.person_nbr
                 AND tmpPersonMedication3.RowNumber = 3
       LEFT JOIN ctePersonMedicationRowNumber tmpPersonMedication4
              ON tmpPersonMedication1.person_nbr = tmpPersonMedication4.person_nbr
                 AND tmpPersonMedication4.RowNumber = 4
       LEFT JOIN ctePersonMedicationRowNumber tmpPersonMedication5
              ON tmpPersonMedication1.person_nbr = tmpPersonMedication5.person_nbr
                 AND tmpPersonMedication5.RowNumber = 5
WHERE  tmpPersonMedication1.RowNumber = 1;

或xPath和cssSelector由开发工具中的chrome生成的字符串。

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

这是html:

enter image description here

3 个答案:

答案 0 :(得分:13)

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内。
  • 您采用的定位器策略标识了该元素,但由于属性 style =“display:none;”的存在而不可见。
  • 您采用的定位器策略 唯一标识 HTML DOM 中的所需元素,并且当前找到了其他隐藏 / 隐藏元素。
  • 您尝试查找的 WebElement 位于<iframe>标记内。
  • 即使在 HTML DOM 中元素存在/可见之前, WebDriver 实例仍在寻找 WebElement

解决方案

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

  • 采用唯一标识所需 WebElement Locator Strategy。您可以获取开发人员工具的帮助( Ctrl + Shift + I F12 )并使用 Element Inspector

    您可以在此处找到有关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 中的元素存在 / 可见,请使用{{WebDriverWait 3}}设置正确的方法如下:

    • 等待ExpectedConditions

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

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

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

答案 1 :(得分:1)

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

尝试在查找元素之前添加长睡眠,如果添加睡眠工作,则更改睡眠等待。

这是代码,它表示如果元素不存在则等待10秒:

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

答案 2 :(得分:-1)

下面的代码将帮助您解决问题

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

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