So l have a problem with locating class while using selenium, I have tried everything l could indeed to successfully locate the class attribute and perform something with it, such as:
driver.find_element_by_tag_name('div button')
driver.web.find_element_by_class_name('btn-secondary-md save-button ng-binding')
Code Sample:
<button class="btn-secondary-md save-button ng-binding" ng-click="$ctrl.showChangeOwnerModal()" ng-bind="'Label.ChangeOwner' | translate">Change Owner</button>
Try to locate by css selector:
driver.find_element_by_css_selector('button.btn-secondary-md.save-button.ng-binding')
If you still get some error like element not clickable, try using explicit waits on the webelement.
Most probably you are facing issue due to synchronization , you can always use WebDriverWait to avoid synchronization issue.
solution 1 :
wait = WebDriverWait(driver, 10)
wait.until(EC.element_to_be_clickable((By.CLASS_NAME, "btn-secondary-md save-button ng-binding")))
solution 2:
wait = WebDriverWait(driver,30)
element = wait.until(EC.element_to_be_clickable((By.XPATH, "//button[contains(text(),'Change Owner')]")))
Note : Please add below imports to your solution
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
If you still facing issue then please check your element is in iframe, if so then you have to switch control to iframe.
Related
I'm trying to do log in into my university site but i receive this error:
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"xpath","selector":"/html/body/div/div/div[2]/div/div/div/div[2]/form/table/tbody/tr[3]/td[2]/input"}
this is the code part:
textboxes3 = browser.find_element_by_xpath("/html/body/div/div/div[2]/div/div/div/div[2]/form/table/tbody/tr[3]/td[2]/input")
textboxes3.click()
textboxes3.send_keys(matricola)
and this is the site inspection:1
Try targeting the element by id:
textboxes3 = browser.find_element_by_id("username")
textboxes3.click()
textboxes3.send_keys(matricola)
Using browser.find_element_by_id("username") should work, but since it's still not finding the element then I suspect one of two issues might be occurring:
The element hasn't loaded yet and selenium needs to wait longer. I recommend using the WebDriverWait class to wait for the element to load.
Websites are divided into iframes, Selenium may be searching for the element in the wrong iframe. If this is the case you will need to use the driver.switch_to.frame function.
I recommend trying this code out first:
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as ec
from selenium.webdriver.common.by import By
w = WebDriverWait(self.driver, 10)
textboxes3 = w.until(ec.presence_of_element_located((By.ID, 'username')))
textboxes3.click()
textboxes3.send_keys('matricola')
import time
driver = webdriver.Chrome()
driver.get("https://www.canva.com/q/pro-signup/")
time.sleep(6)
driver.switch_to.frame(driver.find_element_by_class_name('rbV9vo63iaj7sGd7XwS4h'))
elem = driver.find_element_by_name("//iframe[contains(#name, '_hjRemote')]")
It cant find element last line. i tried contains, starts with and indexing but none worked.
Try using different elements such as the xpath or the id. If that fails then you could select the element by the css selector. If that fails then you could always use a lib like pyautogui to physically click on the web element.
There are total of 6 iframes, The elements you are looking, they are inside
iframe[src^='https://www.canva.com/']
this iframe.
so you need to switch to this frame first :
driver.switch_to.frame(driver.find_element_by_css_selector("iframe[src^='https://www.canva.com/']"))
I would use the below code to click on Sign up with email:
driver = webdriver.Chrome()
driver.maximize_window()
driver.implicitly_wait(30)
driver.get("https://www.canva.com/q/pro-signup/")
wait = WebDriverWait(driver, 10)
wait.until(EC.frame_to_be_available_and_switch_to_it((By.CSS_SELECTOR, "iframe[src^='https://www.canva.com/']")))
wait.until(EC.element_to_be_clickable((By.XPATH, "//span[text()='Sign up with email']/.."))).click()
Imports :
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
In case you want to have a predefined iframe stored, you could something like this :
remote_vars_frame = driver.find_element_by_css_selector("iframe[id='_hjRemoteVarsFrame']")
driver.switch_to.frame(remote_vars_frame)
You can handle this Exception by directly searching for the element without switching to any iframe as below
elem = driver.find_element_by_name("//iframe[contains(#name, '_hjRemote')]")
I'm trying to click on a link on a webpage that has no ID and no individual class. The only thing to lock it down to is the text 'Sessions'.
I have tried:
driver.find_element_by_xpath("//*[contains(text(),'Sessions')]");
driver.find_element_by_xpath("//*[text()='Sessions']");
Both come back with "No such element".
Edit: I have also tried driver.find_element_by_link_text which also didn't work.
I've tried using the full xpath:
/html/body/div/div/div[1]/div/nav/a[3]
To no avail.
That is a link_Text cause it's between anchor tag, use this :
driver.find_element_by_link_text('Sessions').click()
or
A way more good approach is to use ExplicitWaits :
wait = WebDriverWait(driver, 10)
element = wait.until(EC.element_to_be_clickable((By.LINK_TEXT, 'Sessions')))
element.click()
If you want explicit wait you would need to import the below :
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
If the above gives you NoSuchElementException, I would probably suspect this it is in iframe (See the screenshot first tag - I can see body), if it happens to be then in that case you would need to switch to iframe first and continute with this web element.
Code
wait = WebDriverWait(driver, 10)
wait.until(EC.frame_to_be_available_and_switch_to_it((By.XPATH, "iframe xpath here")))
wait.until(EC.element_to_be_clickable((By.PARTIAL_LINK_TEXT, "Sessions"))).click()
Imports :
When I run the code, the website loads up fine but then it won't click on the button- an error appears saying the element is not interacterble. What do I need to do to click the button? I am relatively new to this and would be grateful for any help.
I have already tried finding it by id and tag.
page = driver.get("https://kenpreston.co.uk/author/")
element = driver.find_element_by_id('mk-button-31')
element.click()
SOLVED:
I used driver.find_element_by_link_text and this worked fine.
I have checked the website and noticed that mk-button-31 is an id for a div tag and inside it there is an a tag. Try getting the url from the a tag and do another driver.get instead of clicking on it.
Also the whole div tag is not clickable so that is why you are getting this error.
Use sleep from time library to be sure page fully loaded
from time import sleep
page = driver.get("https://kenpreston.co.uk/author/")
sleep(2)
element = driver.find_element_by_id('mk-button-31')
element.click()
Looks like your element is not clickable you need to replace this id selector with the css and need to wait for the element before click on it.
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
page = driver.get("https://kenpreston.co.uk/author/")
element = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "#mk-button-31 span"))
element.click();
Consider adding Explicit Wait to your script as it might be the case the DOM had finished loading and the button you're looking for is still not there.
The classes you're looking for are:
WebDriverWait
expected_conditions
Suggested code change:
#your other imports here
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions
#your other code here
page = driver.get("https://kenpreston.co.uk/author/")
element = WebDriverWait(driver, 10).until(expected_conditions.element_to_be_clickable((By.ID, "mk-button-31")))
element.click()
More information: How to use Selenium to test web applications using AJAX technology
I m trying to write a script with selenium webdriver python.
When I try to do a
find_element_by_xpath("//*[#id='posted_1']/div[3]")
it says
NoElementFoundException.
Can someone please help me here?
Regards
Bala
If you are getting NoSuchElementException as your provided exception, There may be following reasons :-
May be you are locating with incorrect locator, So you need to share HTML for better locator solution.
May be when you are going to find element, it would not be present on the DOM, So you should implement WebDriverWait to wait until element visible as below :-
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
wait = WebDriverWait(driver, 10)
element = wait.until(EC.visibility_of_element_located((By.XPATH, "//*[#id='posted_1']/div[3]")))
May be this element is inside any frame or iframe. If it is, you need to switch that frame or iframe before finding the element as below :-
driver.switch_to_frame("frame/iframe I'd or name")
wait = WebDriverWait(driver, 10)
element = wait.until(EC.visibility_of_element_located((By.XPATH, "//*[#id='posted_1']/div[3]")))
#Once all your stuff done with this frame need to switch back to default
driver.switch_to_default_content();
that exception, unsurprisingly, means that that element wasn't available on the DOM. There are a couple of options here:
driver.implicitly_wait(10)
will tell the driver to wait 10 seconds (or any amount of time) after an element is not found/not clickable etc., and tries again after. Sometimes elements don't load right away, so an implicit wait fixes those types of problems.
The other option here is to do an explicit wait. This will wait until the element appears, and until the existence of that element is confirmed, the script will not move on to the next line:
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
element = WebDriverWait(ff, 10).until(EC.presence_of_element_located((By.XPATH, "//*[#id='posted_1']/div[3]")))
In my experience, an implicit wait is usually fine, but imprecise.