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 andswitchTo()
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 indexHere 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
Python: Requests.Exceptions.Connectionerror. Max Retries Exceeded With Url
How to Sort a List of Lists by a Specific Index of the Inner List
How to Find the Unit Digits of a Specific Number
Better Way to Extract Only 2Nd Column of a Txt File in Python
How to Hide Tkinter Python Gui
Visual Studio Code Intellisense Is Very Slow - Is There Anything I Can Do
Insert Comma into Text File Using Python
How to Repeat Each Test Multiple Times in a Py.Test Run
Python 2D List Performance, Without Numpy
Numpy: Checking If a Value Is Nat
Create an Array With a Pre Determined Mean and Standard Deviation
Using Pyserial to Send Binary Data
Numpy Distance Calculations of Different Shaped Arrays