So I am learning how to use Selenium for web automation - I am trying to write a script that returns my American Express balance to my console. The first step is actually logging on successfully...
It appears that my action for clicking the login button raises an error of not finding the element, even though I can see it when I am on firebug.
This is my code:
from selenium import webdriver
driver = webdriver.Firefox()
baseurl = "https://www.americanexpress.com/canada/"
username = "myusername"
password = "mypassword"
xpaths = { 'usernameField' : "//input[#id='UserID']",
'passwordField' : "//input[#id='Password']",
'submitButton' : "//input[#id='loginButton']"
}
driver.get(baseurl)
driver.find_element_by_xpath(xpaths['usernameField']).clear()
driver.find_element_by_xpath(xpaths['usernameField']).send_keys(username)
driver.find_element_by_xpath(xpaths['passwordField']).clear()
driver.find_element_by_xpath(xpaths['passwordField']).send_keys(password)
driver.find_element_by_xpath(xpaths['submitButton']).click()
This is the console error message I get, where the browser has filled in my login details, but just has not clicked on the login button:
Traceback (most recent call last):
File "get_balance.py", line 29, in <module>
driver.find_element_by_xpath(xpaths['submitButton']).click()
File "/Library/Python/2.7/site-packages/selenium/webdriver/remote/webdriver.py", line 232, in find_element_by_xpath
return self.find_element(by=By.XPATH, value=xpath)
File "/Library/Python/2.7/site-packages/selenium/webdriver/remote/webdriver.py", line 664, in find_element
{'using': by, 'value': value})['value']
File "/Library/Python/2.7/site-packages/selenium/webdriver/remote/webdriver.py", line 175, in execute
self.error_handler.check_response(response)
File "/Library/Python/2.7/site-packages/selenium/webdriver/remote/errorhandler.py", line 166, in check_response
raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.NoSuchElementException: Message: Unable to locate element: {"method":"xpath","selector":"//input[#id='loginButton']"}
Stacktrace:
at FirefoxDriver.prototype.findElementInternal_ (file:///var/folders/mx/dbnsd72j05zd4k2cls4cvmf00000gn/T/tmpKQDaey/extensions/fxdriver#googlecode.com/components/driver-component.js:10271)
at FirefoxDriver.prototype.findElement (file:///var/folders/mx/dbnsd72j05zd4k2cls4cvmf00000gn/T/tmpKQDaey/extensions/fxdriver#googlecode.com/components/driver-component.js:10280)
at DelayedCommand.prototype.executeInternal_/h (file:///var/folders/mx/dbnsd72j05zd4k2cls4cvmf00000gn/T/tmpKQDaey/extensions/fxdriver#googlecode.com/components/command-processor.js:12274)
at DelayedCommand.prototype.executeInternal_ (file:///var/folders/mx/dbnsd72j05zd4k2cls4cvmf00000gn/T/tmpKQDaey/extensions/fxdriver#googlecode.com/components/command-processor.js:12279)
at DelayedCommand.prototype.execute/< (file:///var/folders/mx/dbnsd72j05zd4k2cls4cvmf00000gn/T/tmpKQDaey/extensions/fxdriver#googlecode.com/components/command-processor.js:12221)
Any thoughts? Any advice/help is much appreciated, thanks!
This is an a element, not an input:
<a tabindex="0" href="#" id="loginButton" title="Login securely">
<span></span>
Log In
</a>
Change your xpath to: //a[#id="loginButton"].
Aside from that, for id attributes there is a find_element_by_id() method:
driver.find_element_by_id("loginButton").click()
Also, if you want to have element locators separated from the actual "action" code, you can configure it the following way (left a single xpath expression for a sake of an example):
from selenium.webdriver.common.by import By
locators = {
'usernameField': (By.ID, "UserID"),
'passwordField': (By.XPATH, "//input[#id='Password']"),
'submitButton': (By.ID, "loginButton")
}
Then, your "action" code would be using find_element():
username = driver.find_element(*locators['usernameField'])
username.clear()
username.send_keys(username)
password = driver.find_element(*locators['passwordField'])
password.clear()
password.send_keys(password)
login_button = driver.find_element(*locators['submitButton'])
login_button.click()
Related
Hello I would like to ask if there is any way to refresh source code of site without refreshing page. The problem is when I load page http://107.170.101.241:8080/getTableColumn/ and put there some information - you can see in my code below and then click Analyse there is displayed new textarea. I want to get text from this textarea but I cant because source code is “old” and xpath cant find it. Last line of code is what I want to print to console. I tried time.sleep etc. and nothing helped.
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import Select
import time
chromedriver = "/usr/local/bin/chromedriver"
driver = webdriver.Chrome(chromedriver)
driver.get("http://107.170.101.241:8080/getTableColumn/")
time.sleep(1)
datab = driver.find_element_by_xpath("//select[#name='dbVendor']")
database = Select(datab)
database.select_by_visible_text("Sybase")
datab2 = driver.find_element_by_xpath("//select[#name='options']")
database2 = Select(datab2)
database2.select_by_visible_text("Show By SQL Clause")
txt = driver.find_element_by_xpath("//textarea[#name='sql']")
txt.clear()
txt.send_keys("select trd.M_NB as 'Trade_number' from CRD_TRADE_REP trd")
txt1 = driver.find_element_by_xpath("//textarea[#name='metadata']")
txt1.clear()
txt1.send_keys("CRD_TRADE_REP, M_NB")
analyze = driver.find_element_by_xpath("//input[#type='submit']")
analyze.send_keys("")
analyze.send_keys(Keys.RETURN)
#cant find this textarea below
out = driver.find_element_by_xpath("//textarea[#name='outputText']")
Here is Traceback:
Traceback (most recent call last):
File "/Users/martinkubicka/Documents/fiverrgde.py", line 32, in <module>
out = driver.find_element_by_xpath("//textarea[#name='outputText']")
File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/selenium/webdriver/remote/webdriver.py", line 394, in find_element_by_xpath
return self.find_element(by=By.XPATH, value=xpath)
File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/selenium/webdriver/remote/webdriver.py", line 976, in find_element
return self.execute(Command.FIND_ELEMENT, {
File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/selenium/webdriver/remote/webdriver.py", line 321, in execute
self.error_handler.check_response(response)
File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/selenium/webdriver/remote/errorhandler.py", line 242, in check_response
raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"xpath","selector":"//textarea[#name='outputText']"}
(Session info: chrome=84.0.4147.135)
In devtools, If you scroll up from your element, you can see your output textarea is nested in:
<iframe name="result" id="result" style="height: 180px; width: 800px;" scrolling="no" frameborder="0">
These need extra handling in selenium.
Try this at the end of your script:
#Get the frame
WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it((By.XPATH,"//iframe[#name='result']")))
#wait for your object to be ready - i use clickable as i like it
out = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH,"//textarea[#name='outputText']")))
print(out.text)
#do stuff your stuff to the "out" element here
#when ready to go back to the main page content (not the iframe)
driver.switch_to_default_content()
When i run your code with that addition i get the output:
Tables: tetSelect CRD_TRADE_REP(1,40) Columns: selectList
CRD_TRADE_REP.M_NB(1,12)
driver.find_element_by_id('username').send_keys('945412')
print 'username entered'
driver.find_element_by_name('password').send_keys('mns347')
print 'password entered'
driver.find_element_by_name("submit").click()
print 'submit'
but it is throwing error
Traceback (most recent call last):
File "C:\Users\SS\Desktop\python-mp\sele_sample.py", line 17, in <module>
driver.find_element_by_id('username').send_keys('945412')
File "C:\Python27\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 360, in find_element_by_id
return self.find_element(by=By.ID, value=id_)
File "C:\Python27\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 978, in find_element
'value': value})['value']
File "C:\Python27\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 321, in execute
self.error_handler.check_response(response)
File "C:\Python27\lib\site-packages\selenium\webdriver\remote\errorhandler.py", line 242, in check_response
raise exception_class(message, screen, stacktrace)
NoSuchElementException: Message: no such element: Unable to locate element: {"method":"id","selector":"username"}
(Session info: chrome=70.0.3538.102)
(Driver info: chromedriver=2.44.609538 (b655c5a60b0b544917107a59d4153d4bf78e1b90),platform=Windows NT 6.3.9600 x86_64)
You can add explicit wait to wait for element to be loaded.
username= WebDriverWait(driver, 2).until(
EC.presence_of_element_located((By.ID, "username"))
)
username.send_keys('945412')
I can't see any mistake in your code. But according to your error message, there is no field with the id username.
Please make sure that there really is a field with the id username on your website.
As an example, githubs username field is defined as follows
<input name="login" id="login_field" class="form-control input-block" tabindex="1" autocapitalize="off" autocorrect="off" autofocus="autofocus" type="text">
In this case you would have to adapt your code to this. This would look like this
driver.find_element_by_id('login_field').send_keys('945412')
Because the field contains id="login_field"
import the by module and try this instead,
from selenium.webdriver.common.by import By
element = driver.find_element(by=By.ID, value="username")
element.send_keys('945412')
use wait like below, if the above code doesn't work username= WebDriverWait(driver, 2).until(
EC.presence_of_element_located((By.ID, "username"))
);
username.send_keys('945412.')
You need to install chromedriver and chrome. You can change these settings for other browsers if you want. This work fine for me.
from selenium import webdriver
browser = webdriver.Chrome("/usr/lib/chromium-browser/chromedriver")
browser.get('<login_url>')
username = browser.find_element_by_name("<username_name_tag>")
password = browser.find_element_by_name("<password_name_tag>")
username.send_keys("<username>")
password.send_keys("<password>")
browser.find_element_by_id("<login_button_id>").click()
I am very new to coding and I am trying to make a form filler on Nike.com using the Selenium Chrome webdriver. However, a pop-up comes up about cookied and I am finding it hard to remove it so I can fill out the form.
This is what it looks like
and my code looks like this:
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import time
#Initialise a chrome browser and return it
def initialisebrowser():
browser=webdriver.Chrome(r'''C:\Users\ben_s\Downloads\chromedriver''')
return browser
#Pass in the browser and url, and go to the url with the browser
def geturl(browser, url):
browser.get(url)
#Initialise the browser (and store the returned browser)
browser = initialisebrowser()
#Go to a url(nike.com) with the browser
geturl(browser,"https://www.nike.com/gb/en_gb/s/register")
button = browser.find_element_by_class_name("nsg-button.nsg-grad--nike-orange.yes-button.cookie-settings-button.js-yes-button")
button.click()
When I run this code, I get this error:
Traceback (most recent call last):
File "C:\Users\ben_s\Desktop\Nike Account Generator.py", line 19, in <module>
button = browser.find_element_by_class_name("nsg-button.nsg-grad--nike-orange.yes-button.cookie-settings-button.js-yes-button")
File "C:\Python\Python36\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 557, in find_element_by_class_name
return self.find_element(by=By.CLASS_NAME, value=name)
File "C:\Python\Python36\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 957, in find_element
'value': value})['value']
File "C:\Python\Python36\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 314, in execute
self.error_handler.check_response(response)
File "C:\Python\Python36\lib\site-packages\selenium\webdriver\remote\errorhandler.py", line 242, in check_response
raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"class name","selector":"nsg-button.nsg-grad--nike-orange.yes-button.cookie-settings-button.js-yes-button"}
(Session info: chrome=67.0.3396.87)
(Driver info: chromedriver=2.38.552522 (437e6fbedfa8762dec75e2c5b3ddb86763dc9dcb),platform=Windows NT 10.0.17134 x86_64)
Any ideas, pointers or solutions to the problem are much apprieciated
find_element_by_class_name recives one class as parameter
browser.find_element_by_class_name('yes-button')
The parameter you provided is combination of all the webelement classes, and is used by css_selector
browser.find_element_by_css_selector('.nsg-button.nsg-grad--nike-orange.yes-button.cookie-settings-button.js-yes-button')
Note that you need to add . before the first class as well, otherwise it is treated as tag name. For example in this case
browser.find_element_by_css_selector('button.nsg-button.nsg-grad--nike-orange.yes-button.cookie-settings-button.js-yes-button')
To make sure the button exists before clicking on it you can use explicit wait
button = WebDriverWait(driver, 10).until(expected_conditions.element_to_be_clickable((By.CLASS_NAME, 'yes-button')))
button.click()
use time.sleep to wait until the popup will load, and after that you can use cookie-settings-button-container class that is parrent of the btn this will work.
time.sleep(1)
button = browser.find_element_by_class_name("cookie-settings-button-container")
button.click()
I'm attempting to create an automated login script to netflix website: https://www.netflix.com/it/
That's the code:
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
driver = webdriver.Firefox()
while True:
driver.get("https://www.netflix.com/it/")
login = driver.find_element_by_css_selector(".authLinks.signupBasicHeader")
login.click()
element = driver.find_element_by_name("email")
element.send_keys("test1#email.com")
submit = driver.find_element_by_css_selector(".btn.login-button.btn-submit.btn-small")
submit.click()
element2 = driver.find_element_by_name("password")
element2.send_keys("test1")
submit.click()
But sometimes it works and sometimes it doesn't and it raises this exception:
Traceback (most recent call last):
File "netflix.py", line 35, in <module>
submit.click()
File "/home/user/.local/lib/python3.5/site-packages/selenium/webdriver/remote/webelement.py", line 72, in click
self._execute(Command.CLICK_ELEMENT)
File "/home/user/.local/lib/python3.5/site-packages/selenium/webdriver/remote/webelement.py", line 461, in _execute
return self._parent.execute(command, params)
File "/home/user/.local/lib/python3.5/site-packages/selenium/webdriver/remote/webdriver.py", line 236, in execute
self.error_handler.check_response(response)
File "/home/user/.local/lib/python3.5/site-packages/selenium/webdriver/remote/errorhandler.py", line 192, in check_response
raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.ElementNotVisibleException: Message: Element is not currently visible and so may not be interacted with
Stacktrace:
at fxdriver.preconditions.visible (file:///tmp/tmp7otgskq8/extensions/fxdriver#googlecode.com/components/command-processor.js:10092)
at DelayedCommand.prototype.checkPreconditions_ (file:///tmp/tmp7otgskq8/extensions/fxdriver#googlecode.com/components/command-processor.js:12644)
at DelayedCommand.prototype.executeInternal_/h (file:///tmp/tmp7otgskq8/extensions/fxdriver#googlecode.com/components/command-processor.js:12661)
at DelayedCommand.prototype.executeInternal_ (file:///tmp/tmp7otgskq8/extensions/fxdriver#googlecode.com/components/command-processor.js:12666)
at DelayedCommand.prototype.execute/< (file:///tmp/tmp7otgskq8/extensions/fxdriver#googlecode.com/components/command-processor.js:12608)
The exception says that a part of the web page is invisible (even if that part IS in the page actually)... It's a sort of bug.
How can I bypass this?
No need to put the test code inside while loop, since login form should be submitted once. I guess when it works successfully, next iteration gives error since there is no form.
You are also clicking the submit button before and after password entry. It is better to click after form is fully filled, if possible and not testing empty form.
from selenium import webdriver
driver = webdriver.Firefox()
driver.get("https://www.netflix.com/it/")
login = driver.find_element_by_css_selector(".authLinks.signupBasicHeader")
login.click()
element = driver.find_element_by_name("email")
element.send_keys("test1#email.com")
submit = driver.find_element_by_css_selector(".btn.login-button.btn-submit.btn-small")
submit.click()
element2 = driver.find_element_by_name("password")
element2.send_keys("test1")
submit = driver.find_element_by_css_selector(".btn.login-button.btn-submit.btn-small")
submit.click()
When trying to click on the Google My Business "Select Photos From My Computer" button I receive this error. I have tried using ever Identifying element type that selenium offers in the Documentation but cant seem to get this button to click.
Traceback (most recent call last):
File "C:/Users/Office/Documents/Development/Web_Postmate.py", line 18, in <module>
elem6 = driver.find_element_by_partial_link_text("Select photos from your computer")
File "C:\Users\Office\AppData\Local\Programs\Python\Python35-32\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 338, in find_element_by_partial_link_text
return self.find_element(by=By.PARTIAL_LINK_TEXT, value=link_text)
File "C:\Users\Office\AppData\Local\Programs\Python\Python35-32\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 744, in find_element
{'using': by, 'value': value})['value']
File "C:\Users\Office\AppData\Local\Programs\Python\Python35-32\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 233, in execute
self.error_handler.check_response(response)
File "C:\Users\Office\AppData\Local\Programs\Python\Python35-32\lib\site-packages\selenium\webdriver\remote\errorhandler.py", line 194, in check_response
raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.NoSuchElementException: Message: Unable to locate element: {"method":"partial link text","selector":"Select a photo from your computer"}
Stacktrace:
at FirefoxDriver.prototype.findElementInternal_ (file:///C:/Users/Office/AppData/Local/Temp/tmpuv4pvvys/extensions/fxdriver#googlecode.com/components/driver-component.js:10770)
at fxdriver.Timer.prototype.setTimeout/<.notify (file:///C:/Users/Office/AppData/Local/Temp/tmpuv4pvvys/extensions/fxdriver#googlecode.com/components/driver-component.js:625)
Here is the Button HTML I have to use "Class" and "Link Text"
<div tabindex="0" class="c-F-U e-d e-d-Ac" role="button" style="-moz-user-select: none;">Select photos from your computer</div>
Here is my source file:
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
driver = webdriver.Firefox()
driver.get("https://business.google.com/b/101831927968068062215/photos/l/03416071574991367502")
elem = driver.find_element_by_name("Email")
elem.send_keys("User")
elem.send_keys(Keys.ENTER)
driver.implicitly_wait(5)
elem1 = driver.find_element_by_name("Passwd")
elem1.send_keys("Password")
elem1.send_keys(Keys.ENTER)
driver.implicitly_wait(5)
elem5 = driver.find_element_by_class_name("tx")
elem5.click()
driver.implicitly_wait(5)
elem6 = driver.find_element_by_partial_link_text("Select photos from your computer")
elem6.click()
You have specified '...a photo...' in your locator while in HTML source text contains '...photos...'
To use both class and link text try:
driver.find_element_by_xpath('//div[#class="c-F-U e-d e-d-Ac"][contains(text(), "Select photos from your computer")]')
Try click by using Actions, in java like below
new Actions(driver).moveToElement(driver.findElement(By.xpath("//*[contains(text(),'Select photos from your computer')]"))).click().build().perform();
if still it does not work, we can try by using javascriptexecutor
WebElement element = driver.findElement(By.xpath("//*[contains(text(),'Select photos from your computer')]"));
JavascriptExecutor executor = (JavascriptExecutor)driver;
executor.executeScript("arguments[0].click();", element);
Thank You,
Murali