Unable to find input element with Selenium and Python - python

I am new in selenium and python.
I trying to find element using selenium but no matter what I tried (xpath, CSS) I always got the following message:
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element
Here the code I wrote :
import time
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.support.ui import WebDriverWait
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import TimeoutException
from time import sleep
from requests_html import HTML
options = Options()
# options.add_argument("--headless")
options.add_argument('disable-notifications')
options.add_argument('--disable-infobars')
options.add_argument('--disable-blink-features=AutomationControlled')
driver = webdriver.Chrome(executable_path=r'C:/Users/XXX/PycharmProjects/chromedriver.exe', options=options)
first_url = "https://www.micromania.fr/jeu-concours-summer-show.html"
driver.get(first_url)
# For the following, it works
refuse = driver.find_element_by_xpath('//*[#id="truste-consent-required"]').click()
time.sleep(2)
But when I tried to do a driver.find_element_by -CSS, Xpath, to find for the mail field to be able to fill it, I met the error message.
HTML of the mail field I tried to reach is there:
<input data-v-0f8f86ae="" type="email" placeholder="Email*" class="input">
UPDATE

You need to first click on the account icon, having class sidebar-login header-link-item icon-account no-decoration color-white. That click will do a XHR network call, which will bring some new elements into page, including email address field. Also, it's wise to wait for elements to load in page before searching them, instead of just searching for them. Also, it's wise to wrap the cookie button dismissal in a try/except block, just in case it's not popping up all the time.
Adapting the following snippet to your code will get you what you're after:
url='https://www.micromania.fr/jeu-concours-summer-show.html'
browser.get(url)
WebDriverWait(browser, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, ".sidebar-login.header-link-item.icon-account.no-decoration.color-white"))).click()
email_field = WebDriverWait(browser, 20).until(EC.element_to_be_clickable((By.XPATH, "//input[#title='Adresse email']")))
email_field.click()
email_field.send_keys('my amazing email address')
print('done')
EDIT: for the email field I'm not able to see (restricted to French IPs only):
email_2_field = WebDriverWait(browser, 20).until(EC.element_to_be_clickable((By.XPATH, "//div[#class='home']/input[#type='email']")))
email_2_field.click()

Given the HTML:
<input data-v-0f8f86ae="" type="email" placeholder="Email*" class="input">
As the desired element is a dynamic element, to send a character sequence within the element you need to induce WebDriverWait for the element_to_be_clickable() and you can use either of the following locator strategies:
Using CSS_SELECTOR:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "input.input[type='email'][placeholder^='Email']"))).click()
Using XPATH:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//input[#class='input' and starts-with(#placeholder, 'Email')][#type='email']"))).click()
Note: You have to add the following imports :
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC

Related

Trying to click an element on a webpage using selenium

I'm trying to write a script to fill out a form but I'm struggling to click the free sim link, I have tried using multiple different identifiers but can't seem to get any to work. Greatly appreciate any help! Thank you
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
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.common.action_chains import ActionChains
import time
PATH = "C:\Program Files (x86)\chromedriver.exe"
driver = webdriver.Chrome(PATH)
driver.get("https://mobile.lebara.com/gb/en/free-sim")
driver.implicitly_wait(5)
cookie = driver.find_element_by_id("onetrust-accept-btn-handler")
freesim = driver.find_element_by_class_name("product-item payAsYouGoProductListerItem clickable")
actions = ActionChains(driver)
actions.click(cookie).perform()
driver.implicitly_wait(5)
actions.click(freesim).perform()
You have to deal with "accept cookies" banner (click on it, you don't need actions, only EC then click)
replace all implicit waits in your code with expected_conditions
(In case all these recommendations don't work for you have to update your question with code and selenium exceptions)
You need to click "Accept cookies" or execute JS code to hide "Your cookies" overlay and then search for link.
driver.implicitly_wait(5)
cookie = driver.find_element_by_id("onetrust-accept-btn-handler")
cookie.click()
freesim = driver.find_element_by_link_text("Free Sim")
freesim.click()
Note that you're trying to pass multiple class names to find_element_by_class_name (you need to pass one only) and call driver.implicitly_wait(5) several times (you might do this only once)
Your class name contains spaces and thus are actually multiple class names. You can make a CSS selector by prefixing each class name with a dot.
CSS Selector ->> ".product-item.payAsYouGoProductListerItem.clickable"
You also have to wait until the element is clickable before you click. Add this to/change this in your code. The rest of your code works fine.
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
....
....
....
freesim = WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, ".product-item.payAsYouGoProductListerItem.clickable")))
freesim.click()
To click on the element Free Sim you can use either of the following Locator Strategies:
Using css_selector:
driver.find_element_by_css_selector("button#onetrust-accept-btn-handler").click()
Using xpath:
driver.find_element_by_xpath("//a[#href='free-sim-direct']").click()
Ideally, to click on the element you need to induce WebDriverWait for the element_to_be_clickable() and you can use either of the following Locator Strategies:
Using CSS_SELECTOR:
driver.get("https://mobile.lebara.com/gb/en/free-sim")
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "button#onetrust-accept-btn-handler"))).click()
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "a[href='free-sim-direct']"))).click()
Using XPATH:
driver.get("https://mobile.lebara.com/gb/en/free-sim")
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//button[#id='onetrust-accept-btn-handler']"))).click()
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//a[#href='free-sim-direct']"))).click()
Note: You have to add the following imports :
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC

Python Selenium element is not visible [duplicate]

I am trying to enter username and password in the following website:
https://www.thegreatcoursesplus.com/sign-in
driver = webdriver.Chrome()
driver.get('https://www.TheGreatCoursesPlus.com/sign-in')
driver.find_element_by_xpath('//h1[#class="sign-in-input"]').click()
This gave following exception:
selenium.common.exceptions.ElementNotVisibleException: Message: element not visible
Then I tried to use java script:
driver.execute_script("document.getElementsByClassName('sign-in-input')[0].click()")
cmd = "document.getElementsByClassName('label-focus')[0].value = 'abc#abc.com'"
driver.execute_script(cmd)
There are no errors but no text is sent to "Email Address" field.
Can someone please guide me on the correct way to enter email address, password and then click "Sign-in".
This error message...
selenium.common.exceptions.ElementNotVisibleException: Message: element not visible
...implies that the desired element was not visible within the HTML DOM while the WebDriver instance was trying to find it.
ElementNotVisibleException
ElementNotVisibleException is thrown when an element is present on the DOM Tree, but it is not visible, and so is not able to be interacted with.
Reason
One possitive take away from ElementNotVisibleException is the fact that the WebElement is present within the HTML and this exception is commonly encountered when trying to click() or read an attribute of an element that is hidden from view.
Solution
As ElementNotVisibleException ensures that the WebElement is present within the HTML so the solution ahead would be two folds as per the next steps as detailed below:
If you next step is to read any attribute of the desired element, then you need to induce WebDriverWait in-conjunction with expected_conditions clause set to visibility_of_element_located as follows:
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
my_value = WebDriverWait(driver, 10).until(EC.visibility_of_element_located((By.XPATH, "element_xpath"))).get_attribute("innerHTML")
If you next step is to invoke click() on the desired element, then you need to induce WebDriverWait in-conjunction with expected_conditions clause set to element_to_be_clickable as follows:
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, "element_xpath"))).click()
This usecase
The xpath you constructed as //h1[#class="sign-in-input"] doesn't match any node. We need to create unique xpath to locate the elements representing Email Address, Password and Sign In button inducing WebDriverWait. The below code block will help you to achieve the same:
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
options = Options()
options.add_argument("start-maximized")
options.add_argument("disable-infobars")
options.add_argument("--disable-extensions")
driver = webdriver.Chrome(chrome_options=options, executable_path="C:\\Utility\\BrowserDrivers\\chromedriver.exe")
driver.get('https://www.TheGreatCoursesPlus.com/sign-in')
WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, "//div[#id='modal']//input[#name='email']"))).send_keys("abc#abc.com")
driver.find_element_by_xpath("//div[#id='modal']//input[#name='password']").send_keys("password")
driver.find_element_by_xpath("//div[#id='modal']//button[#class='color-site sign-in-button']").click()
for username use :
driver.find_element_by_xpath("//input(#type='email')").click()
driver.find_element_by_xpath("//input(#type='email')").send_keys( "username" )
for password use :
driver.find_element_by_xpath("//input(#type='password')").click()
driver.find_element_by_xpath("//input(#type='password')").send_keys( "password" )
There are two problems:
The first one is timing, it takes some time for the form to appear. You you can use explicit wait to solve it.
The second one is that the field id in <input> tag, not <h1> tag, and there are many fields that matches this xpath. I suggest you locate the form holding the fields and use it to locate each field
For the timing issue you can use explicit wait
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.Chrome()
driver.get('https://www.TheGreatCoursesPlus.com/sign-in')
form = WebDriverWait(driver, 10).until(EC.visibility_of_element_located((By.XPATH, '//div[#class="modal-body"]//form')))
form.find_element_by_name('email').send_keys(email)
form.find_element_by_name('password').send_keys(password)
form.find_element_by_name('sign-in-button').click()

Chropath for selenium xpath is not working?

I installed chropath to finding out the xpath for websites.
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
driver = webdriver.Chrome("C:\\Users\\ADMIN\\Downloads\\chromedriver_win32\\chromedriver.exe")
driver.get("https://kite.zerodha.com")
username = driver.find_element_by_xpath("//input[#placeholder='User ID']")
username.send_keys("abcc")
I wanted to find username xpath using chropath and it gave me //input[#placeholder='User ID'] but it is still giving me NoSuchElementException error. I thought chropath extension would always give me correct xpath.
What can be the reason for this ?
This is the code that I get when I inspect Username
<input type="text" placeholder="User ID" autocorrect="off" maxlength="6" autofocus="autofocus" autocapitalize="characters" animate="true" label="" rules="[object Object]" dynamicwidthsize="8" xpath="1">
Functionally, chropath was correct to find the xpath for the desired element. However as the element is having the attribute animate="true", when the element recieves the cursor focus the attribute placeholder="User ID" gets changed as a result Selenium is unable to locate the element.
Solution
To send a character sequence within the User ID field you have to induce WebDriverWait for the element_to_be_clickable() and you can use either of the following Locator Strategies:
Using XPATH:
driver.get('https://kite.zerodha.com/')
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//label[text()='User ID']//following-sibling::input[1]"))).send_keys("TANMAY")
Using CSS_SELECTOR:
driver.get('https://kite.zerodha.com/')
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "label.su-input-label.su-dynamic-label + input"))).send_keys("TANMAY")
Note : You have to add the following imports :
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
Browser Snapshot:
I checked your code and I think it is correct, however, I think you might be missing a .click() element. To make sure that the elements are present you could do the following, where I've added optional wait time for elements to be loaded.
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
# Handle wait time
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait # available since 2.4.0
from selenium.webdriver.support import expected_conditions as EC # available since 2.26.0
driver = webdriver.Chrome("C:\\Users\\ADMIN\\Downloads\\chromedriver_win32\\chromedriver.exe")
driver.get("https://kite.zerodha.com")
wait = WebDriverWait(driver, 60)
username = wait.until(EC.presence_of_element_located((By.XPATH, "//input[#placeholder='User ID']")))
username.click()
username.send_keys("abcc")

Clicking button via python selenium chrome

I would like to click button "ja ik ga akkoord" on url anwb.nl with python selenium chrome. I have copied the relative xpath but when is use it i keep getting NoSuchElementException. Also id, name, etc no luck
I start with:
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
options = Options()
driver = webdriver.Chrome(options=options)
driver.get('https://anwb.nl')
When i inspect the page, xpath of the button gives me:
//*[#id="accept default level"]
When i use this with ...by_xpath i get NoSuchElementException
The code of the button is:
<button class="btn-decide_link-internal" type="button"
name="save"
id="accept default level"> ==$0
Ja, ik ga akkoord</button>
I tried id (accept def...), name (save), but all nosuchelement
In general i would really like to understand how to interpret the web code in general can solve future problems.
The element with text as Ja, ik ga akkoord is within an <iframe> so you have to:
Induce WebDriverWait for the desired frame to be available and switch to it.
Induce WebDriverWait for the desired element to be clickable.
You can use either of the following Locator Strategies:
Using CSS_SELECTOR:
driver.get("https://www.anwb.nl/");
WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it((By.CSS_SELECTOR,"iframe[src*='anwb']")))
WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "button.btn-decide_link-internal"))).click()
Using XPATH:
driver.get("https://www.anwb.nl/");
WebDriverWait(driver,10).until(EC.frame_to_be_available_and_switch_to_it((By.XPATH,"//iframe[contains(#src, 'anwb')]")))
WebDriverWait(driver,10).until(EC.element_to_be_clickable((By.XPATH,"//button[#id='accept default level']"))).click()
Note : You have to add the following imports :
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
Browser snapshot:
Here you can find a relevant discussion on Ways to deal with #document under iframe
There is an iframe.Induce WebDriverWait and switch to frame first and then click on the button.
EC.frame_to_be_available_and_switch_to_it()
EC.element_to_be_clickable()
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 import webdriver
from selenium.webdriver.chrome.options import Options
options = Options()
driver = webdriver.Chrome(options=options)
driver.get('https://anwb.nl')
WebDriverWait(driver,10).until(EC.frame_to_be_available_and_switch_to_it((By.TAG_NAME,"iframe")))
WebDriverWait(driver,10).until(EC.element_to_be_clickable((By.ID,"accept default level"))).click()

selenium using python: how to correctly click() an element?

while learning how to use selenium, Im trying to click an element but nothing happens and Im unable to reach the next page. this is the relevant page: http://buyme.co.il and Im trying to click: הרשמה
I managed to print the desired element (הרשמה) so I guess Im reaching the correct place in the page. but 'click()' doesnt work.
the second span <span>הרשמה</span> is what i want to click:
<li data-ember-action="636">
<a>
<span class="seperator-link">כניסה</span>
<span>הרשמה</span>
</a>
</li>
for elem in driver.find_elements_by_xpath('//* [#id="ember591"]/div/ul[1]/li[3]/a/span[2]'):
print (elem.text)
elem.click()
also tried this:
driver.find_element_by_xpath('//*[#id="ember591"]/div/ul[1]/li[3]/a').click()
I expected to get to the "lightbox" which contain the registration fields.
Any thoughts on the best way to accomplish this?
Explicit Waits - An explicit wait is a code you define to wait for a certain condition to occur before proceeding further in the code.
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
browser = webdriver.Chrome()
browser.get("https://buyme.co.il/")
WebDriverWait(browser, 10).until(EC.element_to_be_clickable((By.ID, 'ember591')))
elm = browser.find_elements_by_xpath('//div[#id="ember591"]/div/ul[1]/li[3]/a')
elm[0].click()
Update:
WebDriverWait(browser, 10).until(EC.element_to_be_clickable((By.CLASS_NAME, 'login')))
email = browser.find_elements_by_xpath("//form[#id='ember1005']/div[1]/label/input")
email[0].send_keys("abc#gmail.com")
password = browser.find_elements_by_xpath("//form[#id='ember1005']/div[2]/label/input")
password[0].send_keys("test1234567")
login = browser.find_elements_by_xpath('//form[#id="ember1005"]/button')
login[0].click()
The desired element is an Ember.js enabled element so to locate the element you have to induce WebDriverWait for the element to be clickable and you can use the following Locator Strategy:
Using XPATH:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//span[text()='הרשמה']"))).click()
Note : You have to add the following imports :
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC

Categories