2

I need to automate a web page using python selenium, but it encounters a reCaptcha, which is in another frame. I want to solve the captcha, and continue the script by clicking the login button, when the reCaptcha has been solved; However, this gets tricky, since a frame is involved, and the frame needs to switch back to the default content. Can anyone help me in this regard?

from selenium import webdriver
from selenium.webdriver import ActionChains
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.support.ui import Select
import time
browser = webdriver.Chrome()
browser.delete_all_cookies()    
browser.maximize_window()
browser.get("https://developer.syntecx.org/ptcl_ebills/signin.php")
browser.switch_to.frame(browser.find_element_by_tag_name("iframe"))
browser.find_element_by_xpath("//*[@id='recaptcha-anchor']/div[1]").click()
time.sleep(20)
browser.switch_to_default_content()
browser.find_element_by_xpath("//*[@id='login']/button").click()
undetected Selenium
  • 183,867
  • 41
  • 278
  • 352
Asad Ullah
  • 43
  • 1
  • 3
  • 7

5 Answers5

3

Once you fill in the Email and Password field to click on the you can use the following Locator Strategies:

  • Code Block:

    options = webdriver.ChromeOptions() 
    options.add_argument("start-maximized")
    options.add_experimental_option("excludeSwitches", ["enable-automation"])
    options.add_experimental_option('useAutomationExtension', False)
    driver = webdriver.Chrome(options=options, executable_path=r'C:\Utility\BrowserDrivers\chromedriver.exe')
    driver.get("https://developer.syntecx.org/ptcl_ebills/signin.php")
    WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "input#email"))).send_keys("Asad_Ullah@stackoverflow.com")
    driver.find_element_by_css_selector("input#password").send_keys("Asad_Ullah")
    WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it((By.CSS_SELECTOR,"iframe[src^='https://www.google.com/recaptcha/api2/anchor?']")))
    WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "span.recaptcha-checkbox.goog-inline-block.recaptcha-checkbox-unchecked.rc-anchor-checkbox"))).click()
    driver.switch_to_default_content()
    WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "button.btn.btn-primary.block.full-width.m-b"))).click()
    
  • Browser Snapshot:

reCAPTCHA

undetected Selenium
  • 183,867
  • 41
  • 278
  • 352
  • Thanks for the help. How do I switch back to the main frame, and continue the script, after I've solved the reCaptcha? That's where I'm getting in trouble. – Asad Ullah Dec 20 '19 at 08:05
  • @AsadUllah Updated the answer with the step to switch back to the main frame and click on the **Login** button. Check out the updated answer and let me know the status. – undetected Selenium Dec 20 '19 at 08:16
  • Does it wait for me to solve the captcha, and then automatically continue the script? Because I ran this in my python compiler, and it just clicks the login button after clicking the captcha. – Asad Ullah Dec 21 '19 at 13:56
  • switch_to_default_content() is deprecatede – vahid sabet Feb 07 '22 at 10:33
1

You can simply wait for the checkbox to show the done icon and then the wait will be over

Like in the code below

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.get("http://somedomain/url_that_delays_loading")
try:
    element = WebDriverWait(driver, 100).until(
        EC.presence_of_element_located((By.ID, "myDynamicElement"))
    )
finally:
    driver.quit() here
1

Try do it:

Create a variable that get the main window:

mainWin = driver.current_window_handle

When u need to switch to main window:

driver.switch_to.window(mainWin)
0

Don't switch to the iframe.

Everything you need is in #g-recaptcha-response and [data-sitekey] which are both in main context.

pguardiario
  • 53,827
  • 19
  • 119
  • 159
0

Here I found a solution when you encounter a reCaptcha in a login page. Simple approach that works very good for me. Check out for login button in a login page. If it lost it's existance, than you can proceed to the next stage. So, my solution does not require any timeout. Happy automating your stuff :)

    def check_exists_by_xpath(xpath):
        try:
            self.driver.find_element_by_xpath(xpath)
        except NoSuchElementException:
            return False
        return True

    login_btn_xpath = 'your login button xpath'
    while True:
        print('You can solve recaptcha during this period and hit the login button.')
        if check_exists_by_xpath(login_btn_xpath) is False:
            break
    # TODO: you can go along from here!