thicccat688 / selenium-recaptcha-solver

ReCAPTCHA solver for selenium (Using audio).
MIT License
105 stars 37 forks source link

Timeout exception: will not solve recaptcha on VFS website #21

Open noramirkh opened 1 year ago

noramirkh commented 1 year ago

Dear developer,

Thank you for your work on this module.

I am trying to solve recaptcha on below page: https://visa.vfsglobal.com/gbr/en/cze/login

It has V2 and V3 captchas, so I am trying to use your module for solving V2 as I guess it is not solving V3.

This is the code I use:

test_driver.get('https://visa.vfsglobal.com/gbr/en/cze/login') recaptcha_iframe = test_driver.find_elements(By.XPATH, '//iframe[@title="reCAPTCHA"]')[0] # as there are 2 reCaptcha iframes I pick first solver.click_recaptcha_v2(iframe=recaptcha_iframe)

I can see script clicks on checkbox, image selection pops up but then selenium throws exception:

solver.click_recaptcha_v2(iframe=recaptcha_iframe) File "\Projects\Python.venv\Lib\site-packages\selenium_recaptcha_solver\solver.py", line 81, in click_recaptcha_v2 captcha_challenge = self._wait_for_element( ^^^^^^^^^^^^^^^^^^^^^^^ File "\Projects\Python.venv\Lib\site-packages\selenium_recaptcha_solver\solver.py", line 230, in _wait_for_element return WebDriverWait(self._driver, timeout).until(ec.visibility_of_element_located((by, locator))) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "\Projects\Python.venv\Lib\site-packages\selenium\webdriver\support\wait.py", line 95, in until
raise TimeoutException(message, screen, stacktrace) selenium.common.exceptions.TimeoutException: Message: Stacktrace: Backtrace: GetHandleVerifier [0x0094A813+48355] (No symbol) [0x008DC4B1] (No symbol) [0x007E5358] (No symbol) [0x008109A5] (No symbol) [0x00810B3B] (No symbol) [0x0083E232] (No symbol) [0x0082A784] (No symbol) [0x0083C922] (No symbol) [0x0082A536] (No symbol) [0x008082DC] (No symbol) [0x008093DD] GetHandleVerifier [0x00BAAABD+2539405] GetHandleVerifier [0x00BEA78F+2800735] GetHandleVerifier [0x00BE456C+2775612] GetHandleVerifier [0x009D51E0+616112] (No symbol) [0x008E5F8C] (No symbol) [0x008E2328] (No symbol) [0x008E240B] (No symbol) [0x008D4FF7] BaseThreadInitThunk [0x75F97D49+25] RtlInitializeExceptionChain [0x776BB74B+107] RtlClearBits [0x776BB6CF+191]

May you check this please and share your thoughts.

Thanks

sambragg commented 1 year ago

I think this is related to the issue I just created - where the iframe's source is different to what the solver code looks for by default.

See #22

thicccat688 commented 1 year ago

Hi,

Thanks for letting me know about this issue. I looked into it, and the issue comes from the iframe's src attribute.

What I've done is change the logic to use //iframe[contains(@src, "recaptcha") and contains(@src, "bframe"). I've tested it for your example and issue #22, and it fixed it.

I have deployed a new version of the package, so please let me know if any more issues arise. Have a nice day!

noramirkh commented 1 year ago

Hello,

Thanks for the fix. So when I go step by step in debug mode it works. But when I run it it is failing.

Traceback (most recent call last): File "\Projects\Python\vfsglobal_appointement.py", line 84, in isAppointementAvailable solver.click_recaptcha_v2(iframe=recaptcha_iframe) File "\Projects\Python.venv\Lib\site-packages\selenium_recaptcha_solver\solver.py", line 81, in click_recaptcha_v2 captcha_challenge = self._wait_for_element( ^^^^^^^^^^^^^^^^^^^^^^^ File "\Projects\Python.venv\Lib\site-packages\selenium_recaptcha_solver\solver.py", line 230, in _wait_for_element return WebDriverWait(self._driver, timeout).until(ec.visibility_of_element_located((by, locator))) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "\Projects\Python.venv\Lib\site-packages\selenium\webdriver\support\wait.py", line 95, in until
raise TimeoutException(message, screen, stacktrace) selenium.common.exceptions.TimeoutException: Message:

Could you please advise is it a bug in your code or I am misusing your module?

Thanks

thicccat688 commented 1 year ago

Hello,

Could you send me your script, so I can see if it's a package-related or a script-related issue? (Please make sure to remove any sensitive data like passwords, personal data, etc)

I tested my changes on that page, and they worked fine, so I suspect it's related to your script.

Thank you for your feedback.

noramirkh commented 1 year ago

Hello,

Please see below:

` from selenium import webdriver from selenium.webdriver.common.keys import Keys from selenium.webdriver.common.by import By from selenium.webdriver.support.wait import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.common.action_chains import ActionChains import selenium.common.exceptions as SelExceptions

import traceback import time from selenium_recaptcha_solver import RecaptchaSolver from selenium_recaptcha_solver import StandardDelayConfig

from solveRecaptcha import solveRecaptcha

class MyWebDriver:

driver = None
def getWebDriver():
    if MyWebDriver.driver != None:
        return MyWebDriver.driver
    PATH = "C:\Program Files (x86)\chromdriver.exe"
    user_agent = 'Mozilla/5.0 (Windows NT 4.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36'
    options = webdriver.ChromeOptions()
    #options.add_argument("--headless")  # Remove this if you want to see the browser (Headless makes the chromedriver not have a GUI)
    options.add_argument("--window-size=1920,1080")
    options.add_argument(f'--user-agent={user_agent}')
    options.add_argument('--no-sandbox')
    options.add_argument("--disable-extensions")
    options.add_experimental_option("detach", True)
    MyWebDriver.driver = webdriver.Chrome(PATH,options=options)
    return MyWebDriver.driver

def getElement(driver, by, locator):
    try:
        elem = WebDriverWait(driver, 100).until(
                EC.presence_of_element_located((by, locator))
            )
        return elem
    except Exception as ex:
        raise

class Country: CZECH = "cze" IRELAND = "irl" SWEDEN = "swe"

class Util: def trace_exception(ex): print("Timeout exception:" + str(ex)) traceback.print_exc()

class VfsGlobal:

def __init__(self, username, password, country) -> None:
    self.username = username
    self.password = password
    self.country = country

    self._baseurl = "https://visa.vfsglobal.com/gbr/en"
    self._loginurl = f"{self._baseurl}/{self.country}/login"

    self._driver = MyWebDriver.getWebDriver()

def isAppointementAvailable(self) -> bool:
    driver = self._driver
    driver.get(self._loginurl)
    usernameInput = None
    wait = WebDriverWait(driver, 10)
    try:
        usernameInput = MyWebDriver.getElement(driver, By.ID, "mat-input-0")
        passwordInput = MyWebDriver.getElement(driver, By.ID, "mat-input-1")
        usernameInput.send_keys(self.username)
        passwordInput.send_keys(self.password)

        solver = RecaptchaSolver(driver=driver,delay_config=StandardDelayConfig(min_delay=1, max_delay=3))
        recaptcha_iframe = driver.find_elements(By.XPATH, '//iframe[@title="reCAPTCHA"]')[0]
        solver.click_recaptcha_v2(iframe=recaptcha_iframe)
        #submit = MyWebDriver.getElement(driver, By.XPATH, "//html/body/app-root/div/app-login/section/div/div/mat-card/form/button")
        submit = wait.until(EC.element_to_be_clickable((By.XPATH, "//html/body/app-root/div/app-login/section/div/div/mat-card/form/button")))
        submit.click()
        #startbooking = MyWebDriver.getElement(driver, By.XPATH, "//html/body/app-root/div/app-dashboard/section[1]/div/div[2]/button")
        startbooking = wait.until(EC.element_to_be_clickable((By.XPATH, "//html/body/app-root/div/app-dashboard/section[1]/div/div[2]/button")))
        startbooking.click()

    except SelExceptions.TimeoutException as ex:
        Util.trace_exception(ex)
    except Exception as ex:
        Util.trace_exception(ex)
        driver.quit()

    time.sleep(10)
    driver.quit()

vfsglobal = VfsGlobal(username="", password="", country=Country.CZECH) vfsglobal.isAppointementAvailable()`