BlandCorporation
BlandCorporation

Reputation: 1344

Selenium in Python: button element seems to vanish after interacting with reCAPTCHA. wha?

I'm trying to interact with a page that requires entry of a username and a passcode, then requires a click on a reCAPTCHA and then a click on a login button. Entry of the username and passcode and clicking on the reCAPTCHA work fine, but after interacting with the reCAPTCHA, the login button element seems to be unfindable by Selenium. The thing is, the login button element is easily found by Selenium before interacting reCAPTCHA. What's going on?

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait as wait

driver = webdriver.Firefox()
driver.get("https://localbitcoins.com/accounts/login/")
time.sleep(2)
element = driver.find_element_by_name("username")
element.send_keys("username")
element = driver.find_element_by_name("password")
element.send_keys("passcode")
time.sleep(1)
# reCAPTCHA
wait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it(driver.find_element_by_xpath('//iframe[contains(@src, "google.com/recaptcha")]')))
wait(driver, 10).until(EC.element_to_be_clickable((By.ID, "recaptcha-anchor"))).click()
# login button
elements = driver.find_elements_by_xpath("//button[contains(text(), 'Login')]")
elements[0].click()

Upvotes: 0

Views: 273

Answers (1)

Andersson
Andersson

Reputation: 52665

To be able to handle "Login" button you have to switch back from iframe after interacting with it:

# reCAPTCHA
wait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it(driver.find_element_by_xpath('//iframe[contains(@src, "google.com/recaptcha")]')))
wait(driver, 10).until(EC.element_to_be_clickable((By.ID, "recaptcha-anchor"))).click()

# Switch to default content
driver.switch_to.default_content()

# login button
elements = driver.find_elements_by_xpath("//button[contains(text(), 'Login')]")
elements[0].click()

P.S. Note that there is no need to use time.sleep(1) before wait(driver, 10). If you need more time to wait - just increase timeout, e.g. wait(driver, 15)

Upvotes: 2

Related Questions