How to Check If an Element Is Present in Selenium (Python 2) Without Throwing a Nosuchelement Exception If It Isn'T

How do I check if an element is present in selenium (python 2) without throwing a NoSuchElement Exception if it isn't?

You can search into page_source, where there are all html tags and content :

if '<button class="">' in self.driver.page_source:
... (do one thing)
else:
... (do another thing)

Check for element without exception if element not found

You can use a try-except block to ignore the exception like this:

from selenium.common.exceptions import NoSuchElementException

try:
driver.find_element_by_xpath(...)
except NoSuchElementException:
print("Element not found")

Selenium Python - Handling No such element exception

You can see if the element exists and then click it if it does. No need for exceptions. Note the plural "s" in .find_elements_*.

elem = driver.find_elements_by_xpath(".//*[@id='SORM_TB_ACTION0']")
if len(elem) > 0
elem[0].click()

No such element exception Selenium

After clicking

driver.find_element_by_id("login-btn").click()

It takes you to another page where the login-submit element is presented.

But you trying to click this element immediately after clicking on element on previous page while the new page is still not loaded.

You should add a wait to wait for that element on the second page to appear before accessing it.

This should work:

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

driver = webdriver.Safari()

wait = WebDriverWait(driver, 20)

driver.get('https://manage.statuspage.io/login')

email = wait.until(EC.visibility_of_element_located((By.ID, "email")))
email.clear()
email.send_keys('XXX')
wait.until(EC.visibility_of_element_located((By.ID, "login-btn"))).click()
wait.until(EC.visibility_of_element_located((By.ID, "login-submit"))).click()


Dealing with 'No such element exception' w/ Python selenium

I think this should do the trick for what you're trying. I am adding the text of each month available in the dropdown to a list, that it will check against before trying to select the current month in the loop.

MonthSelect = Select(driver.find_element_by_id("selectMonth"))
DropDownOptions = []
# seems like you have the string of each month in a list/array already so I will refer to that
for option in MonthSelect.options: DropDownOptions.append(option.text)
for month in MonthList:
if month in DropDownOptions:
MonthSelect.select_by_visible_text("%s" % (month))

Edit:

As @Bob pointed out, you could also catch the Exception as so:

from selenium.common.exceptions import NoSuchElementException

try:
Select(driver.find_element_by_id("selectMonth")).select_by_visible_text("%s" % (month))
except NoSuchElementException:
pass

This way you can try every month, but just pass the months that are not present.

NoSuchElementException, Selenium unable to locate element

NoSuchElementException

org.openqa.selenium.NoSuchElementException popularly known as NoSuchElementException extends org.openqa.selenium.NotFoundException which is a type of WebDriverException.

NoSuchElementException can be thrown in 2 cases as follows :

  • When using WebDriver.findElement(By by) :

    //example : WebElement my_element = driver.findElement(By.xpath("//my_xpath"));
  • When using WebElement.findElement(By by) :

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

As per the JavaDocs just like any other WebDriverException, NoSuchElementException should contain the following Constant Fields :

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)

Reason

The reason for NoSuchElementException can be either of the following :

  • The Locator Strategy you have adopted doesn't identifies any element in the HTML DOM.
  • The Locator Strategy you have adopted is unable to identify the element as it is not within the browser's Viewport.
  • The Locator Strategy you have adopted identifies the element but is invisible due to presence of the attribute style="display: none;".
  • The Locator Strategy you have adopted doesn't uniquely identifies the desired element in the HTML DOM and currently finds some other hidden / invisible element.
  • The WebElement you are trying to locate is within an <iframe> tag.
  • The WebDriver instance is looking out for the WebElement even before the element is present/visibile within the HTML DOM.

Solution

The solution to address NoSuchElementException can be either of the following :

  • Adopt a Locator Strategy which uniquely identifies the desired WebElement. You can take help of the Developer Tools (Ctrl+Shift+I or F12) and use Element Inspector.

    Here you will find a detailed discussion on how to inspect element in selenium3.6 as firebug is not an option any more for FF 56?

  • Use executeScript() method to scroll the element in to view as follows :

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

    Here you will find a detailed discussion on Scrolling to top of the page in Python using Selenium

  • Incase element is having the attribute style="display: none;", remove the attribute through executeScript() method as follows :

    WebElement element = driver.findElement(By.xpath("element_xpath"));
    ((JavascriptExecutor)driver).executeScript("arguments[0].removeAttribute('style')", element)
    element.sendKeys("text_to_send");
  • To check if the element is within an <iframe> traverse up the HTML to locate the respective <iframe> tag and switchTo() the desired iframe through either of the following methods :

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

    Here you can find a detailed discussion on Is it possible to switch to an element in a frame without using driver.switchTo().frame(“frameName”) in Selenium Webdriver Java?.

  • If the element is not present/visible in the HTML DOM immediately, induce WebDriverWait with ExpectedConditions set to proper method as follows :

    • To wait for presenceOfElementLocated :

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

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

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

Reference

You can find Selenium's python client based relevant discussion in:

  • Selenium “selenium.common.exceptions.NoSuchElementException” when using Chrome

Best way to check that element is not present using Selenium WebDriver with java

i usually couple of methods (in pair) for verification whether element is present or not:

public boolean isElementPresent(By locatorKey) {
try {
driver.findElement(locatorKey);
return true;
} catch (org.openqa.selenium.NoSuchElementException e) {
return false;
}
}

public boolean isElementVisible(String cssLocator){
return driver.findElement(By.cssSelector(cssLocator)).isDisplayed();
}

Note that sometimes selenium can find elements in DOM but they can be invisible, consequently selenium will not be able to interact with them. So in this case method checking for visibility helps.

If you want to wait for the element until it appears the best solution i found is to use fluent wait:

public WebElement fluentWait(final By locator){
Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
.withTimeout(30, TimeUnit.SECONDS)
.pollingEvery(5, TimeUnit.SECONDS)
.ignoring(NoSuchElementException.class);

WebElement foo = wait.until(new Function<WebDriver, WebElement>() {
public WebElement apply(WebDriver driver) {
return driver.findElement(locator);
}
});

return foo;
};

Hope this helps)

Unable to find element using Selenium

In this case, you're probably looking for the element before the page loads.

You should use the WebDriverWait class of Selenium and the condition presence_of_element_located of the expected_conditions, as shown in the example below:

from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait


browser.get('https://www.udemy.com/join/login-popup/')
timeout = 20 # Number of seconds before timing out.
email = WebDriverWait(browser, timeout).until(EC.presence_of_element_located((By.ID, 'email--1')))
email.send_keys("example@email.com")

In the above snippet, Selenium WebDriver waits up to 20 seconds before throwing a TimeoutException, unless it finds the element to return within the above time. WebDriverWait, by default, calls the ExpectedCondition every 500 milliseconds until it returns successfully.

Finally, presence_of_element_located is an expectation for determining whether an element is present on a page's DOM, without necessarily implying that the element is visible. When the element is found, the locator returns the WebElement.



Related Topics



Leave a reply



Submit