I have the following Code that goes to a URL(www.example.com), and clicks on a link(Example 1). (This part works fine)
from selenium import webdriver
driver = webdriver.Firefox()
driver.get("https://www.example.com")
link = driver.find_element_by_link_text('Example 1')
link.click()
Now, when we click on 'Example 1' link, it opens a confirmation window, with 2 buttons: 'Yes I am authorized user to this site' and 'No I am a new visitor to this site'
So, I wish to click on 'Yes I am authorized user to this site' and then finally enter my log-in credentials.
I have written these 2 lines, just below the above code, for clicking on that button. But these don't work.
button = driver.find_element_by_name("'Yes I am authorized user to this site'")
button.click()
If it is an alert window, you need to use the Alert command.
#import Alert
from selenium.webdriver.common.alert import Alert
from selenium import webdriver
driver = webdriver.Firefox()
driver.get("https://www.example.com")
link = driver.find_element_by_link_text('Example 1')
link.click()
Alert(driver).accept()
#to dismiss alert
#Alert(driver).dismiss()
I think this would have solved your query.
Based on the comment conversation, I would recommend both using an XPATH search (instead of Name or Id) and waiting for elements to be clickable or loaded. When web-driving or web-scraping, pages may intentionally or accidentally load slowly and this can cause issues if you have pauses or waits either hard coded or non-existent. This snippet of code should allow you to search Google using Selenium and Chromedriver (you can modify the driver function to use Firefox or something else if you'd 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
from selenium.common.exceptions import ElementNotVisibleException
from selenium.webdriver.chrome.options import Options
from time import sleep
def init_driver(drvr_path):
chrome_options = Options()
chrome_options.add_argument("--disable-extensions")
driver = webdriver.Chrome(drvr_path+'chromedriver.exe',chrome_options=chrome_options)
driver.wait = WebDriverWait(driver, 5)
return driver
def lookup(query, driver=None, drvr_path=''):
driver = None
if driver is None:
driver = init_driver(drvr_path)
driver.implicitly_wait(45) # Allow up to 45 Seconds for page to load
driver.get("http://www.google.com")
try:
box = driver.wait.until(EC.presence_of_element_located((By.XPATH, """//*[#id="lst-ib"]""")))
box.send_keys(query)
sleep(3) # Let you see the window open
button = driver.wait.until(EC.element_to_be_clickable((By.XPATH,"""//*[#id="sblsbb"]/button""")))
try:
button.click()
except ElementNotVisibleException, s:
print "Error Handled: "+str(s)
button = driver.wait.until(EC.element_to_be_clickable((By.XPATH,"""//*[#id="sblsbb"]/button""")))
try:
button.click()
except:
print "Could not search Google..."
return
resp=driver.page_source.encode('utf-8')
with open(query+'.html','wb') as f:
f.write(resp)
print 'Wrote the File...'
except:
print("Box or Button not found in google.com")
driver.quit()
For example, if your Chromedriver.exe file was located in your default Python path, you could do something like: lookup('Selenium Python XPATH Examples') and it should download an HTML file of the Google Search results. If you already have a Driver initialized, you could of course pass that to it.
Hope this helps
Try this code, hope it will help you
from selenium import webdriver
import time
driver = webdriver.Chrome('path to chromedriver\chromedriver.exe')
driver.get('https://www.example.com')
driver.maximize_window()
link = driver.find_element_by_link_text('Example 1')
link.click()
handles =driver.window_handles # this will give window handles
driver.switch_to.window(handles[1])
button = driver.find_element_by_name("'Yes I am authorized user to this site'")
button.click()
Related
I click on a specific button on a page, but for some reason there is one of the buttons that I can't click on, even though it's positioned exactly like the other elements like it that I can click on.
The code below as you will notice, it opens a page, then clicks to access another page, do this step because only then can you be redirected to the real url that has the //int.
import datetime
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.firefox.options import Options
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
with open('my_user_agent.txt') as f:
my_user_agent = f.read()
headers = {
'User-Agent': my_user_agent
}
options = Options()
options.set_preference("general.useragent.override", my_user_agent)
options.set_preference("media.volume_scale", "0.0")
options.page_load_strategy = 'eager'
driver = webdriver.Firefox(options=options)
today = datetime.datetime.now().strftime("%Y/%m/%d")
driver.get(f"https://int.soccerway.com/matches/{today}/")
driver.find_element(by=By.XPATH, value="//div[contains(#class,'language-picker-trigger')]").click()
time.sleep(3)
driver.find_element(by=By.XPATH, value="//li/a[contains(#href,'https://int.soccerway.com')]").click()
time.sleep(3)
try:
WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, "//a[contains(#class,'tbl-read-more-btn')]")))
driver.find_element(by=By.XPATH, value="//a[contains(#class,'tbl-read-more-btn')]").click()
time.sleep(0.1)
except:
pass
WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, "//div[#data-exponload='']//button[contains(#class,'expand-icon')]")))
for btn in driver.find_elements(by=By.XPATH, value="//div[#data-exponload='']//button[contains(#class,'expand-icon')]"):
btn.click()
time.sleep(0.1)
I've tried adding btn.location_once_scrolled_into_view before each click to make sure the button is correctly in the click position, but the problem still persists.
I also tried using the options mentioned here:
Selenium python Error: element could not be scrolled into view
But the essence of the case kept persisting in error, I couldn't understand what the flaw in the case was.
Error text:
selenium.common.exceptions.ElementNotInteractableException: Message: Element <button class="expand-icon"> could not be scrolled into view
Stacktrace:
RemoteError#chrome://remote/content/shared/RemoteError.jsm:12:1
WebDriverError#chrome://remote/content/shared/webdriver/Errors.jsm:192:5
ElementNotInteractableError#chrome://remote/content/shared/webdriver/Errors.jsm:302:5
webdriverClickElement#chrome://remote/content/marionette/interaction.js:156:11
interaction.clickElement#chrome://remote/content/marionette/interaction.js:125:11
clickElement#chrome://remote/content/marionette/actors/MarionetteCommandsChild.jsm:204:29
receiveMessage#chrome://remote/content/marionette/actors/MarionetteCommandsChild.jsm:92:31
Edit 1:
I noticed that the error only happens when the element is colored orange (when they are colored orange it means that one of the competition games is happening now, in other words it is live).
But the button is still the same, it keeps the same element, so I don't know why it's not being clicked.
See the color difference:
Edit 2:
If you open the browser normally or without the settings I put in my code, the elements in orange are loaded already expanded, but using the settings I need to use, they don't come expanded. So please use the settings I use in the code so that the page opens the same.
What you missing here is to wrap the command in the loop opening those sections with try-except block.
the following code works. I tried running is several times.
import datetime
import time
from selenium import webdriver
from selenium.webdriver import DesiredCapabilities
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")
caps = DesiredCapabilities().CHROME
caps["pageLoadStrategy"] = "eager"
webdriver_service = Service('C:\webdrivers\chromedriver.exe')
driver = webdriver.Chrome(service=webdriver_service, options=options, desired_capabilities=caps)
wait = WebDriverWait(driver, 10)
today = datetime.datetime.now().strftime("%Y/%m/%d")
driver.get(f"https://int.soccerway.com/matches/{today}/")
wait.until(EC.element_to_be_clickable((By.XPATH, "//div[contains(#class,'language-picker-trigger')]"))).click()
time.sleep(5)
wait.until(EC.element_to_be_clickable((By.XPATH, "//li/a[contains(#href,'https://int.soccerway.com')]"))).click()
time.sleep(5)
try:
wait.until(EC.element_to_be_clickable((By.XPATH, "//a[contains(#class,'tbl-read-more-btn')]")))
driver.find_element(By.XPATH, "//a[contains(#class,'tbl-read-more-btn')]").click()
time.sleep(0.1)
except:
pass
wait.until(EC.element_to_be_clickable((By.XPATH, "//div[#data-exponload='']//button[contains(#class,'expand-icon')]")))
for btn in driver.find_elements(By.XPATH, "//div[#data-exponload='' and not(contains(#class,'status-playing'))]//button[contains(#class,'expand-icon')]"):
btn.click()
time.sleep(0.1)
UPD
We need to open only closed elements. The already opened sections should be stayed open. In this case click will always work without throwing exceptions. To do so we just need to add such indication - click buttons not inside the section where status is currently playing.
I'm trying to learn how to use Selenium to log into a site:Ingram-Micro. I made a script and it worked on a different page: https://news.ycombinator.com/login.
Now I'm trying to apply the same thing to Ingram-Micro and I'm stuck and I don't know what else to try. The problem I'm having is a error/message that says the submit element is not clickable, there is a accept cookies button on the bottom of the page which seems to be causing the problem.
I've tried to account for it but I always get error saying that element doesn't exist. Yet if I don't try to click on the accept cookies element I get the original error saying the submit button isn't clickable. Here is my code:
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.common.exceptions import NoSuchElementException
import time
chrome_options = Options()
chrome_options.add_argument('--headless')
chrome_options.add_argument('--no-sandbox')
url = "https://usa.ingrammicro.com/_layouts/CommerceServer/IM/Login.aspx?
returnurl=//usa.ingrammicro.com/"
driver = webdriver.Chrome(options=chrome_options)
driver.get(url)
def login():
USERNAME = 'email'
PASSWORD = 'password'
element = driver.find_element_by_link_text('I ACCEPT')
if element.is_displayed():
print("Element found")
element.click()
else:
print("Element not found")
driver.find_element_by_id('okta-signin-username').send_keys(USERNAME)
driver.find_element_by_id('okta-signin-password').send_keys(PASSWORD)
driver.find_element_by_id('okta-signin-submit').click()
login()
try:
me = driver.find_element_by_id("login_help-about")
print(f"{me.text} Element found")
except NoSuchElementException:
print('Not found')
driver.quit()
Here are the errors I get:
selenium.common.exceptions.ElementClickInterceptedException: Message: element click intercepted: Element <input class="button button-primary" type="submit" value="Log in" id="okta-signin-submit" data-type="save"> is not clickable at point (365, 560). Other element would receive the click: <p class="cc_message">...</p>
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate
element: {"method":"link text","selector":"I ACCEPT"}
(Session info: headless chrome=84.0.4147.125)
The challenge you face is synchronisation around scripts.
The chain of events on this site is 1) the page is loaded, 2) it kicks off it's javascript, 3) that slides the cookie window into view...
However, after the page is loaded, selenium doesn't know about the scripts so it thinks it is good to go. It's trying to click the button before it's there and gets upset that it can't find it. (NoSuchElementException)
There are different sync strategies - What works here is a webdriverwait to tell selenium to wait (without error) until that your object reached the specified expected conditions.
You can read more about waits and expected conditions here
Try this code.
For the cookie "I ACCEPT" button, I changed the identifier to xpath (since i like xpaths) and wrapped it in webdriverwait, waiting for the object to be clickable...
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.common.exceptions import NoSuchElementException
import time
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
chrome_options = Options()
#chrome_options.add_argument('--headless')
chrome_options.add_argument('--no-sandbox')
url = "https://usa.ingrammicro.com/_layouts/CommerceServer/IM/Login.aspx?returnurl=//usa.ingrammicro.com/"
driver = webdriver.Chrome(options=chrome_options)
driver.get(url)
def login():
USERNAME = 'email'
PASSWORD = 'password'
element = WebDriverWait(driver, 30).until(EC.element_to_be_clickable((By.XPATH, '//a[text()="I ACCEPT"]')))
if element.is_displayed():
print("Element found")
element.click()
else:
print("Element not found")
driver.find_element_by_id('okta-signin-username').send_keys(USERNAME)
driver.find_element_by_id('okta-signin-password').send_keys(PASSWORD)
driver.find_element_by_id('okta-signin-submit').click()
login()
Note that i had to remove headless to check it worked and there are 3 additional imports at the top.
Webdriverwait is great when you don't have lots of complicated objects, or have ojects with different wait conditions.
An alternative sync and (Easier in my opionin) is to set an implicit wait ONCE at the start of your script - and this configures the driver objecct.
driver.implicitly_wait(10)
As that link earlier says:
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. The default setting is 0. Once set, the implicit wait is
set for the life of the WebDriver object.
You can use it like this .. not doing all the code, just add this one line added after you create your driver and your code worked:
.....
url = "https://usa.ingrammicro.com/_layouts/CommerceServer/IM/Login.aspx?returnurl=//usa.ingrammicro.com/"
driver = webdriver.Chrome(options=chrome_options)
driver.get(url)
driver.implicitly_wait(10) # seconds
def login():
USERNAME = 'email'
PASSWORD = 'password'
element = driver.find_element_by_link_text('I ACCEPT')
if element.is_displayed():
print("Element found")
element.click()
else:
print("Element not found")
........
You probably need to click on the div above the input. try somethin like this:
child = driver.find_element_by_id('okta-signin-submit')
parent = child.find_element_by_xpath('..') # get the parent
parent.click() # click parent element
UPDATE: This worked great on geckodrive without headless, but not with chromedrive. so instead i've tried something else. Instead of clicking the button, lets just hit enter in the form and submit it this way:
from selenium.webdriver.common.keys import Keys
...
driver.find_element_by_id('okta-signin-username').send_keys(USERNAME)
password_field = driver.find_element_by_id('okta-signin-password')
password_field.send_keys(PASSWORD)
password_field.send_keys(Keys.RETURN)
I'm trying Python and Selenium. My goal is to log myself into Discord (https://discordapp.com/login. But here is the problem. I can't manage to get the email and password box selected. But the worst part is trying to select a textbox on a server... I tried everything, even locating by XPath, but I can't seem to do it right. Also, doing it on ATOM is probably not the best idea since I don't get any error messages :P. Here is a snippet to select the email textbox.
from selenium
import webdriver
from selenium.webdriver.common.keys
import Keys
browser = webdriver.Firefox()
browser.get('https://discordapp.com/login')
assert 'discordapp' in browser.title
elem = browser.find_element_by_name('textarea')# this is the part where i need help
elem.send_keys('test' + Keys.ENTER)
For email this css selector should work :
input[type='email']
For password :
input[type='password']
I've tested this code :
browser.get("https://discordapp.com/login")
elem = browser.find_element_by_css_selector("input[type='email']")# this is the part where i need help
elem.send_keys("itsolidude#imail.com")
elem1 = browser.find_element_by_css_selector("input[type='password']")# this is the part where i need help
elem1.send_keys("password")
login_button = browser.find_element_by_xpath("//div[text()='Login']/parent::button")
login_button.click()
This worked fine on my machine.
you need to check the div container and add them into the xpath.
Try the following code and please debug the indents, in case that stackoverflow is not transferring them properly (well, I don't know how to do it nice and correctly.)
from selenium import webdriver
from selenium.webdriver.common.by import By
import time
class loginPage():
def test(self):
baseUrl = 'https://discordapp.com/login'
driver = webdriver.Firefox(executable_path="G:\\webdriver/geckodriver.exe")
driver.maximize_window()
driver.implicitly_wait(5)
driver.get(baseUrl)
mail = driver.find_element(By.XPATH, "//div[3]/div[1]/div/input[contains(#type,'email')]")
time.sleep(5)
mail.send_keys("test#gmail.com")
time.sleep(3)
print("Enter mail adress")
password = driver.find_element(By.XPATH, "//div[3]/div[2]/div/input[contains(#type,'password')]")
time.sleep(5)
password.send_keys("123456789")
time.sleep(3)
print("Enter password")
time.sleep(10)
driver.quit()
ff = loginPage()
ff.test()
Login To Discord Website using Python and Selenium:
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import Select
driver = webdriver.Chrome()
driver.get("https://discord.com/login")
time.sleep(6)
username_input = driver.find_element_by_name('email')
username_input.send_keys("enter-your-username-here")
password_input = driver.find_element_by_name('password')
password_input.send_keys("Enter-your-password-here")
login_button = driver.find_element_by_xpath('//*[#id="app-mount"]/div[2]/div/div[2]/div/div/form/div/div/div[1]/div[3]/button[2]')
login_button.click()
I am using selenium to automate search in a website.
Here is my code.
import time
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.common.exceptions import TimeoutException
def init_driver():
driver = webdriver.Firefox()
driver.wait = WebDriverWait(driver, 5)
return driver
def lookup(driver, query):
driver.get("www.example.com/search.php")
try:
button = driver.wait.until(EC.element_to_be_clickable(
(By.ID, "ad")))
button.click()
# query = "telugu"
# box = driver.wait.until(EC.element_to_be_clickable(
# (By.NAME, "keytext")))
# box.send_keys(query)
submit_text = "SEARCH"
submit_button = driver.wait.until(EC.element_to_be_clickable(
(By.XPATH, "(//*[contains(text(), '" + submit_text + "')] | //*[#value='" + submit_text + "'])")))
submit_button.click()
print 'aaaa'
except TimeoutException:
print("Box or Button not found in google.com")
if __name__ == "__main__":
driver = init_driver()
lookup(driver, "Selenium")
time.sleep(1000)
driver.quit()
I log in to the site in firefox and then run this script.
Expected url opens up properly (This url open only when I am signed in),clicks the search button.
The results appear for a few seconds and then the Sign In screen is shown.
But I am not actually logged out because If I open this site in a different tab,I am signed in.
I am not understanding this strange behaviour with selenium.Is the site somehow detecting that it is a bot which is trying to click?
Can anyone please tell me how to fix or bypass this?
I suspect that you are experiencing expected behavior with your product. You mentioned that you manually open a browser and login, then run the script. When your script runs, Selenium will open a new browser w/ a new profile, which means that it won't have any cookies that are probably being used for authentication on your site.
You will have to modify your script so that it logs in with valid credentials before it attempts to do the remaining steps.
I am getting very frustrated trying to login to costar.com with python and selenium. I have tried it on the chrome browser and firefox browser, but can't figure out the correct code.
I have logged into other websites, but cannot figure out how to input text into the login boxes for this site.
Here's what I have so far:
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
browser = webdriver.Chrome(executable_path="C:/Users/Gus Gabel/Anaconda/chromedriver.exe")
browser.get("http://www.costar.com")
browser.maximize_window()
#the username and password boxes are hidden until you press the login button on the home page
login = browser.find_element_by_id("loginLink")
login.click()
#now that the username and password boxes are available, I've tried finding the elements by class_name, xpath, (BY.NAME), id, etc and nothing has worked
#here are a few codes that haven't worked and the errors associated
user = browser.find_element_by_id('username')
NoSuchElementException: Message: no such element
user = browser.find_element_by_class_name('usernameNew')
NoSuchElementException: Message: no such element
#when i try to use the above code with "elements" instead of "element", no error message pops up.
user = browser.find_elements_by_class_name('usernameNew')
#but then whey i try to choose which element by doing this
user = browser.find_element_by_class_name('usernameNew')[0]
NoSuchElementException: Message: no such element
How is it possible that there can be a list of elements, but yet not have an initial element?
If anyone can figure out how to input text into the username and password text boxes of costar.com, I will be greatly appreciative. I can't figure this out for the life of me!
To enter text into an input box with Selenium (e.g, your user name into the username field), use the send_keys method of the element:
input_element.send_keys('some_text_string')
You can also try Selenium's action_chains module, as in the following code (untested), to get past the roadblock from #dm295's answer:
from selenium import webdriver
from selenium.webdriver.common import action_chains
driver = webdriver.Firefox()
driver.maximize_window()
driver.get("http://www.costar.com")
action = action_chains.ActionChains(driver)
login = driver.find_element_by_class_name("login-icon")
login.click()
driver.switch_to.frame(driver.find_element_by_id('custlogin'))
username = driver.find_element_by_id('username')
action.move_to_element(username).perform()
username.send_keys('Gus Gabel')
A couple of things:
(a) you have to wait until the page is loaded (or at least the part of the page that you are interested in)
(b) only maximized browser window works for me (depends on device/resolution)
(c) you are trying to click the wrong element
import time
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.maximize_window()
driver.get("http://www.costar.com")
try:
# wait 15 seconds till the login link is present
login = WebDriverWait(driver, 15).until(
EC.presence_of_element_located((By.CLASS_NAME, "login-icon"))
)
login.click()
# just sleep 5 seconds to show that the login link was clicked
time.sleep(5)
# do other stuff (probably fill in username and password) ...
finally:
driver.quit()
Read the documentation regards waiting in selenium.
EDIT
Manged to get one step further (switch to iframe), but the following code raises
selenium.common.exceptions.ElementNotVisibleException: Message:
Element is not currently visible and so may not be interacted with
from selenium import webdriver
driver = webdriver.Firefox()
driver.maximize_window()
driver.get("http://www.costar.com")
try:
login = driver.find_element_by_class_name("login-icon")
login.click()
# switch to the custlogin iframe
driver.switch_to.frame(driver.find_element_by_id('custlogin'))
username = driver.find_element_by_id('username')
# this will raise:
# selenium.common.exceptions.ElementNotVisibleException: Message:
# Element is not currently visible and so may not be interacted with
username.send_keys('username')
finally:
driver.quit()