Selenium: NoSuchElementException even after using explicit Wait - python

I am locating an element on http://ntry.com/#/stats/ladder/round.php,
but I keep failing locating it, after trying several ways, including
ind_element_by_css_selector, ind_element_by_xpath... and so on.
Even though I used WebDriverWait, I keep failing. What would be the Problem?
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
from selenium.webdriver import ActionChains
driver = webdriver.Firefox()
driver.get("http://ntry.com/#/stats/ladder/round.php")
try:
element = EC.presence_of_element_located((By.XPATH, '//div[#id="analysis-table"]/div[1]/div[1]/p[1]/span[1]/strong'))
#or element = WebDriverWait(driver, 30).until(
EC.presence_of_element_located((By.CSS_SELECTOR, "#analysis-table>div.bar_graph>div:nth-child(1)>p.left.on>span.per>strong"))
)
except:
print "HIJUDE"
driver.quit()
I used Implicit wait, but that also makes same error.
Not using Wait makes NoSuchElementException too.
selenium.common.exceptions.NoSuchElementException: Message: Unable to locate element: {"method":"xpath","selector":'//div[#id="analysis-table"]/div[1]/div[1]/p[1]/span[1]/strong'}
Is the website related with being unable to find the Element? or using method other than Xpath or css_selector would do? I am pretty confused why this happened.
-------------Edit--------------
I found out that there is iframe at the upper xpath level of div[#id="analysis-table"]. I guess that's the reason. Should I always use driver.switch_to_frame()
in this case? Btw, is driver.switch_to_window() different from frame()?

You have a problem in p.left.on in the path. One element has single class left and the other one classes right and on. It should be
"#analysis-table>div.bar_graph>div:nth-child(1)>p.left>span.per>strong"
Or
"#analysis-table>div.bar_graph>div:nth-child(1)>p.right.on>span.per>strong"

Related

Selenium - can't find element by xpath

This is the page I am trying to scrape: https://directory.brcgs.com/site/10005068
My code:
bk_btn = driver.find_element_by_xpath("//button [#class='BackButton_backButton__3Czsm']")
bk_btn.click()
This is the error I receive:
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"xpath","selector":"//button [#class='BackButton_backButton__3Czsm']"}
Why am I getting this error and how can I correct it?
Your locator is correct.
It's quite clear that you are missing a delay.
You need to make the element completely loaded before clicking it.
The preferred way to do that is to use WebDriverWait explicit waits as following:
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
wait = WebDriverWait(driver, 20)
wait.until(EC.element_to_be_clickable((By.XPATH, "//button[#class='BackButton_backButton__3Czsm']"))).click()

Selenium: Element Click Intercepted while submitting a form

So I'm trying to submit a form but something is either preventing me from accessing the box or I'm using a wrong element but I think I'm using the correct one.
Here is my code:
from selenium import webdriver
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
driver = webdriver.Chrome(executable_path = 'mypath/chromedriver.exe')
driver.maximize_window()
#driver.implicitly_wait(50)
driver.get("https://ai.fmcsa.dot.gov/SMS")
wait = WebDriverWait(driver, 20)
wait.until(EC.element_to_be_clickable((By.XPATH, "//a[#title='Close']"))).click()
wait = WebDriverWait(driver, 20)
driver.find_element_by_xpath('//*[#id="home-body"]/div[1]/div/div[1]/form/label').click()
driver.find_element_by_xpath('//*[#id="home-body"]/div[1]/div/div[1]/form/label').send_keys('1818437')
driver.find_element_by_xpath('/html/body/div[3]/div[2]/article/section[2]/div[1]/div/div[1]/form/input[2]').click();
What I'm getting on the output is
ElementClickInterceptedException: Message: element click intercepted:
Element ... is
not clickable at point (553, 728). Other element would receive the
click:
(Session info: chrome=93.0.4577.63)
What might be the issue?
Things to noted down in this scenario :-
When you define an explicit waits wait = WebDriverWait(driver, 20), you can always use wait reference in the scope. you do not need to create again and again in same class.
Try to avoid absolute xpath /html/body/div[3]/div[2]/article/section[2]/div[1]/div/div[1]/form/input[2], try with relative xpath/xpath axes.
When we try to send keys to some element, in general it should be a input tag, not label
You may have to scroll, may be not in this case but when you scroll manually to interact with elements in UI, same has to automated with Selenium as well.
Also I observed to this webapp that search and input tags are duplicated, so I have used xpath indexing [2] to handle.
Sample code :-
driver = webdriver.Chrome(executable_path = 'mypath/chromedriver.exe')
driver.maximize_window()
#driver.implicitly_wait(50)
driver.get("https://ai.fmcsa.dot.gov/SMS")
wait = WebDriverWait(driver, 20)
wait.until(EC.element_to_be_clickable((By.XPATH, "//a[#title='Close']"))).click()
wait.until(EC.element_to_be_clickable((By.XPATH, "(//input[#name='MCSearch'])[2]"))).send_keys('1818437')
wait.until(EC.element_to_be_clickable((By.XPATH, "(//input[#name='search'])[2]"))).click()
You can use below xpaths too.
driver.find_element_by_xpath("//div[#class='sms-search-box']//input[1]").send_keys('1818437')
driver.find_element_by_xpath("//div[#class='sms-search-box']//input[2]").click()
Xpath you are using is not right. Your xpath for the input field should be like this.
driver.find_element_by_xpath("//input[#name='MCSearch' and #placeholder='Type Name or U.S. DOT#']").send_keys("1818437")
driver.find_element_by_xpath("//input[#placeholder='Type Name or U.S. DOT#']//following::input[#value='Search']").click();

Selenium not blocking for element

I am facing inconsistencies in Selenium execution.
Last line in the code snippet I pasted below doesn't execute consistently. Sometimes it works, sometimes it throws an error saying that element is not found. Doesn't Selenium "block" for the element to appear before attempting to execute the click? I generated it using Selenium IDE. What I am missing here?
self.driver.find_element(By.CSS_SELECTOR, ".dx-ellipsis:nth-child(2)").click()
self.driver.switch_to.default_content()
self.driver.find_element(By.CSS_SELECTOR, "#PageContentPlaceHolder_TimeControlSplitter_TimeControlContent_TimesheetEntrySplitter_TimesheetDetailsMenu_DXI0_T > .dxm-contentText").click()
Selenium may not find elements if they happen to be loaded dynamically by JS and if you search for them before they are loaded.
You can try either an implicit wait or an explicit wait.
In case of implicit waiting, the docs say:
An implicit wait tells WebDriver to poll the DOM for a certain amount of time when trying to find any element (or elements) not immediately available.
You could do with something like:
from selenium import webdriver
driver = webdriver.Chrome()
driver.implicitly_wait(10) #wait and poll for 10 seconds
Whereas the explicit waiting means to explicitly specify the element which is to be waited for it to be available. As per the docs:
An explicit wait is a code you define to wait for a certain condition to occur before proceeding further in the code.
You can do this with something like:
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.Firefox()
driver.get("http://somedomain/url_that_delays_loading")
element1 = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.CSS_SELECTOR, ".dx-ellipsis:nth-child(2)")))
element1.click()
self.driver.switch_to.default_content()
element2 = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.CSS_SELECTOR, "#PageContentPlaceHolder_TimeControlSplitter_TimeControlContent_TimesheetEntrySplitter_TimesheetDetailsMenu_DXI0_T > .dxm-contentText")))
element2.click()
As you are using the line of code:
self.driver.switch_to.default_content()
Presumably you are switching Selenium's focus from a frame or iframe to the Top Level Content. Hence you need to induce WebDriverWait for the desired element to be clickable and you can use the following Locator Strategy:
self.driver.switch_to.default_content()
WebDriverWait(self.driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "#PageContentPlaceHolder_TimeControlSplitter_TimeControlContent_TimesheetEntrySplitter_TimesheetDetailsMenu_DXI0_T > .dxm-contentText"))).click()
Note:
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
References
You can find a couple of relevant detailed discussions in:
How to send text to the Password field within https://mail.protonmail.com registration page?
How to switch between iframes using Selenium and Python?
Wait for the element to be loaded
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
WebDriverWait(self.driver, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, ".dx-ellipsis:nth-child(2)"))).click()
self.driver.switch_to.default_content()
WebDriverWait(self.driver, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "#PageContentPlaceHolder_TimeControlSplitter_TimeControlContent_TimesheetEntrySplitter_TimesheetDetailsMenu_DXI0_T > .dxm-contentText"))).click()
The number is how long the driver should spend looking for the element before moving on.

How to select a textbox using selenium in python

HTMLI want to select a textbox using XPath or any other locator, but I am unable to do so. The code is working fine for one part of the page, while it is not working using any locator for the other half of the page. I am not sure if my code is wrong or if something else is the problem.
I have attached the HTML part.
Here is my code:
import selenium
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
driver = webdriver.Chrome()
driver.get('Website')
driver.implicitly_wait(50)
driver.find_element_by_xpath('//*[#id="j_username"]').send_keys("Username")
driver.find_element_by_xpath('//*[#id="j_password"]').send_keys("Password")
driver.find_element_by_xpath('//*[#id="b_submit"]').click()
driver.find_element_by_xpath('//*[#id="15301"]/div[1]/a/span').click()
driver.find_element_by_xpath('//*[#id="22261"]/a').click()
driver.find_element_by_xpath('//*[#id="22323"]/a').click()
driver.implicitly_wait(50)
driver.find_element_by_xpath('//*[#id="filterRow"]').clear()
The last line is where I am getting the following error:
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"xpath","selector":"//*[#id="filterRow"]"}
Page may have not finished rendering when you try to find the element. So it will give NoSuchElementException
Try the following method
elem = driver.find_element_by_xpath('//*[#id="filterRow"]')
if len(elem) > 0
elem[0].clear()
Hope this will help you
You can wait till the elements loads using wait -
from selenium.webdriver.support import expected_conditions as EC
wait = WebDriverWait(driver, 20)
Filter_Row = wait.until(EC.visibility_of_element_located((By.XPATH, '//*[#id="filterRow"]')))
Filter_Row.clear()
Try the above code and see what happens.
Try below solution
wait = WebDriverWait(driver, 20)
wait.until(EC.element_to_be_clickable((By.XPATH, "//*[#id='filterRow']"))).clear()
Note: add below imports to your solution :
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
As in one of comments, you mentioned upon clicking tab a new page is opening. Can you please check if its opening in a new frame. Is so please switch to frame first where your element is using below statement:
driver.switch_to.frame(driver.find_element_by_name(name))
To navigate back to original frame you can use:
driver.switch_to.default_content()
using 'find_element_by_css_selector'
driver.find_element_by_css_selector("input")

python selenium can't interact with input element? [duplicate]

This question already has answers here:
ElementNotVisibleException: Message: element not interactable error while trying to click a button through Selenium and Python
(2 answers)
Closed 3 years ago.
I'm trying to put my name in an input field. It seems like a simple thing that selenium is built to do, but I cannot figure out what I'm doing wrong.
name = driver.find_element_by_xpath('//input[#id="signUpName16"]')
name.send_keys('Josh')
I know the driver works because I've been able to click other elements. I know the xpath is right because I copied it from chrome inspector. The error I get is
selenium.common.exceptions.ElementNotInteractableException: Message: element not interactable
I've seen people say to try clicking or clearing elements so I've tried that too, but that still failed.
name = driver.find_element_by_xpath('//input[#id="signUpName16"]')
name.click()
name.send_keys('Josh')
yields this for the name.click() line
selenium.common.exceptions.ElementNotInteractableException: Message: element not interactable
There's a few different things that can be going wrong here. If the input is not fully loaded, then it will throw this exception if you try to send_keys before it is ready. We can invoke WebDriverWait on the input element to ensure it is fully loaded before sending keys to it:
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
input = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, "//input[contains(#id, 'signUpName')]")))
input.send_keys("Josh")
If this still throws the exception, we can instead try to set the input value through Javascript:
input = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, "//input[contains(#id, 'signUpName')]")))
driver.execute_script("arguments[0].value = 'Josh';", input)
If neither of these solutions work, we may need to see some of the HTML on the page you are working with to see if there's any other issue happening here.
ElementNotInteractableException occurs when
Element is not displayed,
Element is out of screen ,
Some time element is hidden or
Behind to another element
Please refer below code to solve this issue:
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait as Wait
from selenium.webdriver.common.action_chains import ActionChains
driver = webdriver.Chrome(executable_path=r"C:\New folder\chromedriver.exe")
driver.set_page_load_timeout("10")
driver.get("your url")
actionChains = ActionChains(driver)
element = WebDriverWait(driver, 10).until(
EC.visibility_of_element_located((By.XPATH, "//input[#id='signUpName16']")))
actionChains.move_to_element(element).click().perform()
Solution 2:
element = WebDriverWait(driver, 10).until(
EC.visibility_of_element_located((By.XPATH, "//input[starts-with(#id,signUpName')]"))) # if your signUpName16 element is dynamic then use contains method to locate your element
actionChains.move_to_element(element).click().perform()

Categories

Resources