import webbrowser
from selenium import webdriver
browser = webdriver.Chrome()
browser.maximize_window()
browser.get('https://www.suntrust.com/')
browser.implicitly_wait(15)
elem = browser.find_element_by_css_selector('input#sign-on-3A69E29D-79E0-
403E-9352-5261239ADD89-user')
elem.click().send_keys('your-username')
element not visible exception error message:
I'm trying to sign into the login/password field automatically, but I keep getting this error message.
I have tried various "find_element_by" locators, but this one was recommended, so I don't think the css selector is the problem. What am I doing wrong?
It happens usually because the dom wouldn't have loaded and the Selenium script tries to find that element .. Make sure this element is not inside an Iframe . Use the selenium explicit wait until the element loads and then perform action on that button . You have to do something like this in python . The below code is just creating a wait object and then waiting for the element to load and perform next step
from selenium.webdriver.support.ui import WebDriverWait
myElem = WebDriverWait(browser, delay).until(EC.presence_of_element_located((By.ID, 'IdOfMyElement')))
print "Page is ready!"
except TimeoutException:
print "Loading took too much time!"
Here is the Answer to your Question:
The css_selector you constructed was not unique and was matching to 2 elements on the HTML DOM. The first match was invisible while the second match was our expected element. Selenium was trying to click the first element. Hence the error. Here is your own code with the modified css_selector which works well at my end:
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
options = Options()
options.add_argument("start-maximized")
options.add_argument("disable-infobars")
options.add_argument("--disable-extensions")
browser = webdriver.Chrome(chrome_options=options, executable_path="C:\\Utility\\BrowserDrivers\\chromedriver.exe")
browser.get('https://www.suntrust.com/')
browser.implicitly_wait(15)
elem = browser.find_element_by_css_selector('section[role="main"] input[id="sign-on-3A69E29D-79E0-403E-9352-5261239ADD89-user"]')
elem.send_keys('your-username')
Let me know if this Answers your Question.
Related
I am making a Python script with the Selenium Chrome Webdriver to automate this website: https://nordicwellness.se/logga-in/?redirecturl=/mina-sidor/ (it's a Swedish website).
I am trying to automate the login process but I keep getting errors such as:
selenium.common.exceptions.ElementNotInteractableException: Message: element not interactable
and
Keyboard not reachable
I am using the following code to locate the email input field and password input field:
emailInp = driver.find_element(By.XPATH, '//*[#id="UserName"]').send_keys('test')
passwordInp = driver.find_element(By.XPATH, '//*[#id="Password"]').send_keys('123')
I've tried passing multiple options and even used the WebDriverWait function, even tried Firefox and Safari, but nothing seems to work.
Is it possible that the website has some kind of security feature that doesn't allow automated scripts? If so, is there a way to bypass it?
You are using not unique locators. There are 3 elements matching //*[#id="UserName"] and //*[#id="Password"] locators.
Locators should be always unique. In this case you need to take in account the unique parent element to make locators unique.
The following code works:
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
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")
webdriver_service = Service('C:\webdrivers\chromedriver.exe')
driver = webdriver.Chrome(options=options, service=webdriver_service)
wait = WebDriverWait(driver, 10)
url = "https://nordicwellness.se/logga-in/?redirecturl=/mina-sidor/"
driver.get(url)
wait.until(EC.element_to_be_clickable((By.XPATH, "//main//input[#id='UserName']"))).send_keys('test')
wait.until(EC.element_to_be_clickable((By.XPATH, "//main//input[#id='Password']"))).send_keys('123')
The result screenshot is:
I believe it is due to your XPath. If you inspect the web elements in the page itself, there are actually 3 elements matched the XPath you entered //*[#id="UserName"]. Without specifying, Selenium will always match the first return element. Which is hidden in the top menu. This is why you get the error of element not interactable.
A quick solution is to use the direct full XPath as per below :
emailInp = driver.find_element(By.XPATH, '/html/body/div[1]/main/div/div/div/form/input[1]').send_keys('test')
passwordInp = driver.find_element(By.XPATH, '/html/body/div[1]/main/div/div/div/form/input[2]').send_keys('123')
Or you need to specifically filter out which //*[#id="UserName"] you trying to access, for an example :
emailInp = driver.find_element(By.XPATH, '//main//*[#id="UserName"]').send_keys('test')
passwordInp = driver.find_element(By.XPATH, '//main//*[#id="Password"]').send_keys('123')
I have a script that uses Selenium (Python).
I tried to make the code click a button that it acknowledges is clickable, but throws an error stating it;s not clickable.
Same thing happens again in a dropdown menu, but this time I'm not clicking, but selecting an option by value.
from selenium import webdriver
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.common.by import By
from selenium.webdriver.support.select import *
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
# Getting to Chrome and website
website = 'https://www.padron.gob.ar/publica/'
driver = webdriver.Chrome(ChromeDriverManager().install())
driver.get(website)
driver.maximize_window()
#"BUENOS AIRES" in "Distrito Electoral"
distritoElectoralOptions = driver.find_element(By.NAME, 'site')
Select(distritoElectoralOptions).select_by_value('02 ')
#Clicking "Consulta por Zona
WebDriverWait(driver, 35).until(EC.element_to_be_clickable((By.ID, 'lired')))
consultaPorZona = driver.find_element(By.ID, 'lired')
consultaPorZona.click()
#"SEC_8" in "Sección General Electoral"
WebDriverWait(driver, 35).until(EC.visibility_of((By.NAME, 'secg')))
seccionGeneralElectoral = driver.find_element(By.NAME, 'secg')
Select(seccionGeneralElectoral).select_by_value('00008')
I'm getting this error on line 21:
selenium.common.exceptions.ElementNotInteractableException: Message: element not interactable: element has zero size
It works in a ipython notebook if each section is separated, but only if the option "Run all" is not used. Instead, the kernel has to be run on it's own.
I'm using VS Code.
Also, when it reaches the last line, when run in ipynb format, it throws this error:
Message: Cannot locate option with value: 00008
Thank you in advance.
When a web element is present in the HTML-DOM but it is not in the state that can be interacted. Other words, when the element is found but we can’t interact with it, it throws ElementNotInteractableException.
The element not interactable exception may occur due to various reasons.
Element is not visible
Element is present off-screen (After scrolling down it will display)
Element is present behind any other element
Element is disabled
If the element is not visible then wait until element is visible. For this we will use wait command in selenium
wait = WebDriverWait(driver, 10)
element = wait.until(EC.element_to_be_clickable((By.ID, 'someid')))
element.click()
If the element is off-screen then we need to scroll down the browser and interact with the element.
Use the execute_script() interface that helps to execute JavaScript methods through Selenium Webdriver.
browser = webdriver.Firefox()
browser.get("https://en.wikipedia.org")
browser.execute_script("window.scrollTo(0,1000)") //scroll 1000 pixel vertical
Reference this solution in to the regarding problem.
I've tried using getText() Referencing, but when I use that method I always get the error "WebElement object has no attribute getText()". I found .text through a YouTube video but I'm not getting results from it either. Any thoughts?
from selenium import webdriver
driverPath = 'C:\Program Files (x86)\chromedriver.exe'
driver = webdriver.Chrome(driverPath)
driver.implicitly_wait(20)
driver.get ('https://shop.pricechopper.com/search?search_term=lettuce')
pageSource = driver.page_source
search = driver.find_elements_by_class_name ("css-dr3s47")
print (search[0].text)
driver.quit()
You are using Selenium with Python, so correct method is .text
.getText() is for Selenium-Java Bindings.
The reason why are you getting null is cause elements are not rendered properly and you are trying to interact with them resulting in null.
Please use Explicit wait or time.sleep() which is worst case to get rid of this issue.
Also, there's a pop window that we will have to click on close web element, so that css-dr3s47 will be available to Selenium view port.
Code :
driver = webdriver.Chrome(driver_path)
driver.maximize_window()
driver.implicitly_wait(30)
wait = WebDriverWait(driver, 30)
driver.get("https://shop.pricechopper.com/search?search_term=lettuce")
try:
wait.until(EC.element_to_be_clickable((By.XPATH, "//button[#ng-click='processModalCloseClick()']"))).click()
print('Clicked on modal pop up closer button')
except:
pass
search = driver.find_elements_by_class_name ("css-dr3s47")
print (search[0].text)
Imports :
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
getText returns elements with rendered size more than 0 * 0 , so if element is not displayed of has size zero , then it wont return anything .
Two things you could do is :
scroll to the element before getting text
Actions actionProvider = new Actions(driver);
// Performs mouse move action onto the element
actionProvider.moveToElement(search[0]).build().perform();
print(search[0].text)
Use textCOntent
Text content doesn't check for display or size , it just gives content
print(search[0].get_attribute("textContent"))
I am having trouble selecting a load more button on a Linkedin page. I receive this error in finding the xpath: selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element
I suspect that the issue is that the button is not visible on the page at that time. So I have tried actions.move_to_element. However, the page scrolls just below the element, so that the element is no longer visible, and the same error subsequently occurs.
I have also tried move_to_element_with_offset, but this hasn't changed where the page scrolls to.
How can I scroll to the right location on the page such that I can successfully select the element?
My relevant code:
import parameters
from selenium.webdriver.common.action_chains import ActionChains
from selenium import webdriver
ChromeOptions = webdriver.ChromeOptions()
driver = webdriver.Chrome('C:\\Users\\Root\\Downloads\\chromedriver.exe')
driver.get('https://www.linkedin.com/login?fromSignIn=true&trk=guest_homepage-basic_nav-header-signin')
sleep(0.5)
username = driver.find_element_by_name('session_key')
username.send_keys(parameters.linkedin_username)
sleep(0.5)
password = driver.find_element_by_name('session_password')
password.send_keys(parameters.linkedin_password)
sleep(0.5)
sign_in_button = driver.find_element_by_xpath('//button[#class="btn__primary--large from__button--floating"]')
sign_in_button.click()
driver.get('https://www.linkedin.com/in/kate-yun-yi-wang-054977127/?originalSubdomain=hk')
loadmore_skills=driver.find_element_by_xpath('//button[#class="pv-profile-section__card-action-bar pv-skills-section__additional-skills artdeco-container-card-action-bar artdeco-button artdeco-button--tertiary artdeco-button--3 artdeco-button--fluid"]')
actions = ActionChains(driver)
actions.move_to_element(loadmore_skills).perform()
#actions.move_to_element_with_offset(loadmore_skills, 0, 0).perform()
loadmore_skills.click()
After playing around with it, I seem to have figured out where the problem is stemming from. The error
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"xpath","selector":"//button[#class="pv-profile-section__card-action-bar pv-skills-section__additional-skills artdeco-container-card-action-bar artdeco-button artdeco-button--tertiary artdeco-button--3 artdeco-button--fluid"]"}
(Session info: chrome=81.0.4044.113)
always correctly states the problem its encountering and as such it's not able to find the element. The possible causes of this include:
Element not present at the time of execution
Dynamically generated
content Conflicting names
In your case, it was the second point. As the content that is displayed is loaded dynamically as you scroll down. So When it first loads your profile the skills sections aren't actually present in the DOM. So to solve this, you simply have to scroll to the section so that it gets applied in the DOM.
This line is the trick here. It will position it to the correct panel and thus loading and applying the data to the DOM.
driver.execute_script("window.scrollTo(0, 1800)")
Here's my code (Please change it as necessary)
from time import sleep
# import parameters
from selenium.webdriver.common.action_chains import ActionChains
from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait
ChromeOptions = webdriver.ChromeOptions()
driver = webdriver.Chrome('../chromedriver.exe')
driver.get('https://www.linkedin.com/login?fromSignIn=true&trk=guest_homepage-basic_nav-header-signin')
sleep(0.5)
username = driver.find_element_by_name('session_key')
username.send_keys('')
sleep(0.5)
password = driver.find_element_by_name('session_password')
password.send_keys('')
sleep(0.5)
sign_in_button = driver.find_element_by_xpath('//button[#class="btn__primary--large from__button--floating"]')
sign_in_button.click()
driver.get('https://www.linkedin.com/in/kate-yun-yi-wang-054977127/?originalSubdomain=hk')
sleep(3)
# driver.execute_script("window.scrollTo(0, 1800)")
sleep(3)
loadmore_skills=driver.find_element_by_xpath('//button[#class="pv-profile-section__card-action-bar pv-skills-section__additional-skills artdeco-container-card-action-bar artdeco-button artdeco-button--tertiary artdeco-button--3 artdeco-button--fluid"]')
actions = ActionChains(driver)
actions.move_to_element(loadmore_skills).perform()
#actions.move_to_element_with_offset(loadmore_skills, 0, 0).perform()
loadmore_skills.click()
Output
Update
In concerns to your newer problem, you need to implement a continuous scroll method that would enable you to dynamically update the skills section. This requires a lot of change and should ideally be asked as a another question.
I have also found a simple solution by setting the scroll to the correct threshold. For y=3200 seems to work fine for all the profiles I've checked including yours, mine and few others.
driver.execute_script("window.scrollTo(0, 3200)")
If the button is not visible on the page at the time of loading then use the until method to delay the execution
try:
myElem = WebDriverWait(browser, delay).until(EC.presence_of_element_located((By.ID, 'IdOfMyElement')))
print "Button is rdy!"
except TimeoutException:
print "Loading took too much time!"
Example is taken from here
To get the exact location of the element, you can use the following method to do so.
element = driver.find_element_by_id('some_id')
element.location_once_scrolled_into_view
This actually intends to return you the coordinates (x, y) of the element on-page, but also scroll down right to target element. You can then use the coordinates to make a click on the button. You can read more on that here.
You are getting NoSuchElementException error when the locators (i.e. id / xpath/name/class_name/css selectors etc) we mentioned in the selenium program code is unable to find the web element on the web page.
How to resolve NoSuchElementException:
Apply WebDriverWait : allow webdriver to wait for a specific time
Try catch block
so before performing action on webelement you need to take web element into view, I have removed unwated code and also avoided use of hardcoded waits as its not good practice to deal with synchronization issue. Also while clicking on show more button you have to scroll down otherwise it will not work.
from selenium import webdriver
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.common.action_chains import ActionChains
driver = webdriver.Chrome(executable_path="path of chromedriver.exe")
driver.get('https://www.linkedin.com/login?fromSignIn=true&trk=guest_homepage-basic_nav-header-signin')
driver.maximize_window()
WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.NAME, "session_key"))).send_keys("email id")
WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.NAME, "session_password"))).send_keys("password ")
WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.XPATH, "//button[#class='btn__primary--large from__button--floating']"))).click()
driver.get("https://www.linkedin.com/in/kate-yun-yi-wang-054977127/?originalSubdomain=hk")
driver.maximize_window()
driver.execute_script("scroll(0, 250);")
buttonClick = WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.XPATH, "//span[text()='Show more']")))
ActionChains(driver).move_to_element(buttonClick).click().perform()
Output:
import webbrowser
from selenium import webdriver
browser = webdriver.Chrome()
browser.get('https://www.suntrust.com/')
browser.implicitly_wait(10)
elem = browser.find_element_by_xpath('//*[#id="sign-on-3A69E29D-79E0-403E-
9352-5261239ADD89-user"]')
elem.send_keys('your-username')
I'm having two problems:
1) The window doesn't open up in full screen, meaning the username field isn't physically visible. How do I open the url in a new tab instead of a new window.
2) Other posts suggest that the element is faked by JavaScript so that webdriver can't see it.
I've tried find_element_by in all the other locators.
Your question should be answered by a simple line of code that you need to include
browser.maximize_window()
would maximise your window. Another option is to set a specific window size like
driver.set_window_size(1280, 1024)
You can use both to achieve the browser being open to a maximum size.
Another point that I would make is that, if you're a beginner, try using more of CSS Selectors instead of the Xpath. They are much faster than Xpath's. Please see a detailed post on SQA about what makes a good locator.
For your case, the CSS Selector for the sign in field would be
driver.find_element_by_css_selector('input#sign-on-3A69E29D-79E0-403E-9352-5261239ADD89-user')
For password, it would be
driver.find_element_by_css_selector('input#sign-on-3A69E29D-79E0-403E-9352-5261239ADD89-password')
For Sign On button it would be
driver.find_element_by_css_selector('button.suntrust-login-button')
Please read more about CSS Selectors and try using them more often in your code.
Here is the Answer to your Question:
The xpath you have constructed is not unique. The xpath matches exactly to 2 elements on the HTML DOM. So Selenium was trying to send_keys on the first matching element which was invisible. Hence the error element not visible. The xpath used in the following code block identifies the User ID field uniquely and sends the text:
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
options = Options()
options.add_argument("start-maximized")
options.add_argument("disable-infobars")
options.add_argument("--disable-extensions")
browser = webdriver.Chrome(chrome_options=options, executable_path="C:\\Utility\\BrowserDrivers\\chromedriver.exe")
browser.get('https://www.suntrust.com/')
browser.implicitly_wait(15)
elem = browser.find_element_by_xpath('//section[#role="main"]//input[#id="sign-on-3A69E29D-79E0-403E-9352-5261239ADD89-user"]')
elem.send_keys('your-username')
Let me know if this Answers your Question.
If you use absolute xpath then you can send the text in textbox.
Below code will do that
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
browser = webdriver.Chrome()
browser.maximize_window() # to open full size window
browser.get('https://www.suntrust.com/')
# browser.implicitly_wait(10)
WebDriverWait(browser, 10).until(
EC.presence_of_element_located((By.XPATH, '//*[#id="sign-on-3A69E29D-79E0-403E-9352-5261239ADD89-user"]')))
elem = browser.find_element_by_xpath("//div[#id='suntrust-login-form-herosignon']/div[2]/form/div[1]/input[1]")
elem.send_keys('your-username')
elem1 = browser.find_element_by_xpath("//div[#id='suntrust-login-form-herosignon']/div[2]/form/div[2]/input[1]")
elem1.send_keys('your-password')