Python Selenium Click Button Within A Class - python

In the image above I am trying to click the 'Continue with email' button. This is the code I have:
from selenium import webdriver
Driver = webdriver.Firefox() #Define webdriver to use
Driver.get('https://www.airbnb.co.uk/login')
Element = Driver.find_element_by_xpath("//div[contains(#class,'_p03egf') and (#class, '_18m31f1b')]")
Element.click
Either my syntax is wrong or my poor understanding of web pages is letting me down
Any help - much appreciated
Thanks
Rob

You can use below solutions, if you want to click on a Continue with email button:
- XPATH
Example 1
wait = WebDriverWait(Driver, 30)
wait.until(EC.presence_of_element_located((By.XPATH, "//div[contains(text(),'Continue with email')]"))).click()
Example 2
wait = WebDriverWait(Driver, 30)
wait.until(EC.presence_of_element_located((By.XPATH, "//div[#class='_bc4egv gs_copied']"))).click()
- CSS Selector
wait = WebDriverWait(Driver, 30)
wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, ".\_18m31f1b:nth-child(1) .\_bc4egv"))).click()
Dont forget to add below imports
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

I think your XPath is off, from the example you gave, I would assume you want something like this:
Element = Driver.find_element_by_xpath("//button[#data-testid='social-auth-button-email']")
w3schools.com has a great tutorial on XPath syntax

Can you try this code
Element = Driver.find_element_by_xpath('//*[#id="site-content"]/div/div/div/div/div/div/div/div[2]/button')

find_elements_by_class_name('_18m31f1b').click()
It should be enough to do what you want as the button seems to be connected to that class and all you want to do is click it.

Related

Python Selenium click google "I agree" button

I am trying to scrape some google data but I first want to click the 'I agree' button that google pops up. This is the script I use to do that:
import time
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
search_question = input("Ask a question: ")
driver = webdriver.Chrome("*Your Webdriver location*")
driver.wait = WebDriverWait(driver, 5)
driver.get("https://google.com")
time.sleep(1)
agree = driver.wait.until(EC.presence_of_element_located((By.XPATH, '//*[#id="introAgreeButton"]/span/span')))
agree.click()
# time.sleep(0.2)
search = driver.find_element_by_class_name("gLFyf")
search.send_keys(search_question)
search.send_keys(Keys.ENTER)
The problem is selenium doesn't seem to locate the button and therefore I get a timeout error. (I have tried also with find_element_by_xpath and still not working).
If you scroll up in the devtools inspector you'll notice that your element is within an iframe:
You need to switch to that frame first, click your button then switch back to the default content (the main page)
driver.get("https://google.com")
#active the iframe and click the agree button
WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it((By.XPATH, "//iframe")))
agree = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, '//*[#id="introAgreeButton"]/span/span')))
agree.click()
#back to the main page
driver.switch_to_default_content()
That works for me.
FYI - There's only 1 iframe on the page, that's why the xpath //iframe works. If there were multiple you'd need to identify it with higher accuracy.
If you already have been agreed,then agree button would not appear. That why it is not be able to find given XPath.
Try this:
import time
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
search_question = input("Ask a question: ")
driver = webdriver.Chrome(".\chromedriver.exe")
driver.wait = WebDriverWait(driver, 5)
driver.get("https://google.com")
time.sleep(3)
# agree = driver.wait.until(EC.presence_of_element_located((By.XPATH, '//*[#id="introAgreeButton"]/span/span')))
# agree.click()
# time.sleep(0.2)
search = driver.find_element_by_class_name("gLFyf")
search.send_keys(search_question)
search.send_keys(Keys.ENTER)
Managed to get it working.
Seems like one of the few elements that are interactive in the popup when you first load the site is the language dropdown, which I found by class name.
Then the Agree button is detectable and you can find it by class too.
driver.get("https://www.google.com")
driver.maximize_window()
time.sleep(2)
#finds+clicks language dropdown, interaction unhides the rest of the popup html
driver.find_element_by_class_name('tHlp8d').click()
time.sleep(2)
#finds+clicks the agree button now that it has become visible
driver.find_element_by_id('L2AGLb').click()
you should now have the standard searchbar etc
i had some problems with clicking pop-ups and the problem turned out to be with that click().
im not sure that it might be the same issue with urs or not but try changing ur click to this :
agree = driver.find_element_by_xpath('//*[#id="introAgreeButton"]/span/span')
driver.execute_script("arguments[0].click();", agree)
The problem was that it didn't change frames here is the soulution code:
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
driver = webdriver.Chrome('C:\\Users\\gassp\\OneDrive\\Namizje\\Python.projects\\chromedriver.exe')
url = 'https://www.google.com/maps/'
driver.get(url)
WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it((By.XPATH, '//*[#id="consent-bump"]/div/div[1]/iframe')))
agree = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, '//*[#id="introAgreeButton"]/span/span')))
agree.click()
#back to the main page
driver.switch_to_default_content()
WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, '//*[#id="searchboxinput"]'))).send_keys('gostilne')
driver.submit()

Click() function in Selenium not working in Python

Here is the website I am trying to scrape: https://www.horrycounty.org/bookings
I have developed a for-loop to cycle through the dates, all I need is to write a simple block of code to click on the "search" button, but I am having some difficulty.
My thoughts are
search = driver.find_element_by_class_name('btn btn-primary')
search.click()
This is my first time using selenium, any help would be welcome.
Try to use JavaScript for the click element (that worked for me):
search = driver.find_element_by_css_selector("span.btn-primary")
driver.execute_script("arguments[0].click();", search)
Try this:
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
search = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.CLASS_NAME, 'btn btn-primary')))
search.click()
Try using a CSS Selector span.btn-primary to click on the button:
from selenium import webdriver
URL = "https://www.horrycounty.org/bookings"
driver = webdriver.Chrome()
driver.get(URL)
search = driver.find_element_by_css_selector("span.btn-primary")
search.click()

how to simulate the hover of cursor python selenium

I want to click on button on web site, but this button appears after you put your cursor on the right place, otherwise you can not see this button. I tried to ignore that and do just normal click by finding the element by xpath. But that did not work out, there was mistake:
selenium.common.exceptions.ElementNotInteractableException: Message: element not
interactable: element has zero size
How to deal with that?
To hover over the element you can use something like this:
from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
chrome= webdriver.Chrome()
chrome.get('http://foo.bar')
element = chrome.find_element_by_css_selector("the_element_u_want")
hover = ActionChains(chrome).move_to_element(element)
hover.perform()
if the element takes time to appear use selenium's wait or time.sleep()
find more info about ActionChains here
this is some code I found here.
Usually, the ElementNotInteractableException is thrown when the element hasn't loaded completely. Here's a possible solution:
from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
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('C:\\Users\\dell\\Libs\\chromedriver.exe')
driver.get("http://url")
driver.maximize_window()
# wait for element to appear, then hover it
wait = WebDriverWait(driver, 10)
men_menu = wait.until(ec.visibility_of_element_located((By.XPATH, "//a[#data-tracking-id='men']")))
ActionChains(driver).move_to_element(men_menu).perform()
This method worked well for me.
def hoverXPATH(xpath):
item = WebDriverWait(driver, 10)\
.until(EC.visibility_of_element_located((By.XPATH, xpath)))
ActionChains(driver).move_to_element(item).perform()

Selenium Webdriver won't find element in xblock

I don't know if the question even makes sense - I'm very new to Python and Selenium and coding in general.
The story is I'm trying to automate the process of saving edX course webpages as HTML. I'm using the latest iPython and Webdriver. This is what I've done so far:
from selenium import webdriver
driver = webdriver.Chrome(executable_path=r'/Users/Khoa_Ngo\bin\chromedriver\chromedriver.exe')
driver.get('https://courses.edx.org/login')
#logging in
driver.find_element_by_id('login-email').send_keys('EMAIL')
driver.find_element_by_id('login-password').send_keys('PASSWORD')
driver.find_element_by_xpath('//*[#type="submit"]').click()
#choosing course
driver.find_element_by_xpath('//*[#href="/courses/course-v1:Microsoft+DEV262x+1T2020a/course/"]').click()
What I want to do next is to save the webpage as HTML, store it somewhere, and then click "Next" to proceed to the next course module and repeat. But I can't seem to locate the button. Here is what I've tried:
driver.find_element_by_xpath('/html/body/div[3]/div[2]/div[2]/div[1]/section[1]/main/div/div/div[1]/button[2]').click()
driver.find_element_by_css_selector('#sequence_adf942ea-fcee-289c-a1f8-3c557ee5fb15 > div.sequence-nav > button.sequence-nav-button.button-next')
I don't think this element is in an iframe. However it's in some kind of "xblock". I'm not sure how that will affect the selection.
This is the webpage I saved: https://drive.google.com/drive/folders/1Zr6sGO0j-H-Tze_lBgkLnQXuQA0pxsWr?usp=sharing
Are these information enough to answer my question? Thank you for your help!
Try below xpath :
wait = WebDriverWait(driver, 10)
wait.until(EC.element_to_be_clickable((By.XPATH, "//button[#class='sequence-nav-button button-next'][contains(.,'Next')]"))).click()
or
wait = WebDriverWait(driver, 10)
wait.until(EC.element_to_be_clickable((By.XPATH, "//button[#class='sequence-nav-button-label'][contains(.,'Next')]")))
You can also try javascript click::
wait = WebDriverWait(driver, 10)
nextbutton= wait.until(EC.element_to_be_clickable((By.XPATH, "//button[#class='sequence-nav-button-label'][contains(.,'Next')]")))
driver.execute_script("arguments[0].click();", nextbutton)
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

How to click a button on a website by finding its id

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

Categories