diff --git a/examples/cloudflare/cloudflare_challenge_page.py b/examples/cloudflare/cloudflare_challenge_page.py index 10ab98a..70c5d4e 100644 --- a/examples/cloudflare/cloudflare_challenge_page.py +++ b/examples/cloudflare/cloudflare_challenge_page.py @@ -6,6 +6,7 @@ from selenium.webdriver.support.wait import WebDriverWait from selenium.webdriver.common.by import By from selenium.webdriver.support import expected_conditions as EC +from selenium.common.exceptions import TimeoutException from selenium.webdriver.chrome.service import Service from selenium.webdriver.chrome.options import Options from twocaptcha import TwoCaptcha @@ -17,6 +18,7 @@ url = "https://2captcha.com/demo/cloudflare-turnstile-challenge" apikey = os.getenv('APIKEY_2CAPTCHA') +solver = TwoCaptcha(apikey) """ When a web page first loads, some JavaScript functions and objects (such as window.turnstile) may already be initialized @@ -53,9 +55,9 @@ # GETTERS -def get_element(locator): - """Waits for an element to be clickable and returns it""" - return WebDriverWait(browser, 30).until(EC.element_to_be_clickable((By.XPATH, locator))) +def get_present_element(locator): + """Waits for an element to be present and returns it""" + return WebDriverWait(browser, 30).until(EC.presence_of_element_located((By.XPATH, locator))) # ACTIONS @@ -89,18 +91,15 @@ def get_captcha_params(script): print("Parameters received") return params -def solver_captcha(apikey, params): +def solver_captcha(params): """ Solves the Turnstile captcha using the 2Captcha service. Args: - apikey (str): The 2Captcha API key. params (dict): The intercepted Turnstile parameters. - Returns: - str: The solved captcha token. + dict: The captcha id and the solved captcha code. """ - solver = TwoCaptcha(apikey) try: result = solver.turnstile(sitekey=params["sitekey"], url=params["pageurl"], @@ -108,8 +107,8 @@ def solver_captcha(apikey, params): data=params["data"], pagedata=params["pagedata"], useragent=params["userAgent"]) - print(f"Captcha solved") - return result['code'] + print(f"Captcha solved. Token: {result['code']}.") + return result except Exception as e: print(f"An error occurred: {e}") return None @@ -125,15 +124,38 @@ def send_token_callback(token): browser.execute_script(script) print("The token is sent to the callback function") -def final_message(locator): +def final_message_and_report(locator, id): """ - Retrieves and prints the final success message. + Retrieves and prints the final success message and sends a report to 2Captcha. + + Submitting answer reports is not necessary to solve the captcha. But it can help you reduce the cost of the solution + and improve accuracy. We have described why it is important to submit reports in our blog: + https://2captcha.com/ru/blog/reportgood-reportbad + + We recommend reporting both incorrect and correct answers. Args: locator (str): The XPath locator of the success message. + id (str): The captcha id for reporting. """ - message = get_element(locator).text - print(message) + try: + # Check for success message + message = get_present_element(locator).text + print(message) + is_success = True + + except TimeoutException: + # If the element is not found within the timeout + print("Timed out waiting for success message element") + is_success = False + except Exception as e: + # If another error occurs + print(f"Error retrieving final message: {e}") + is_success = False + + # Send the report anyway + solver.report(id, is_success) + print(f"Report sent for id: {id}, success: {is_success}") # MAIN LOGIC @@ -148,15 +170,21 @@ def final_message(locator): browser.get(url) print("Started") + # Getting captcha params params = get_captcha_params(intercept_script) if params: - token = solver_captcha(apikey, params) + # Sent captcha to the solution in 2captcha API + result = solver_captcha(params) - if token: + if result: + # From the response from the service we get the captcha id and token + id, token = result['captchaId'], result['code'] + # Applying the token on the page send_token_callback(token) - final_message(success_message_locator) - time.sleep(5) + # We check if there is a message about the successful solution of the captcha and send a report on the result + # using the captcha id + final_message_and_report(success_message_locator, id) print("Finished") else: print("Failed to solve captcha") diff --git a/examples/cloudflare/cloudflare_turnstile.py b/examples/cloudflare/cloudflare_turnstile.py index 41484c6..9bf19cc 100644 --- a/examples/cloudflare/cloudflare_turnstile.py +++ b/examples/cloudflare/cloudflare_turnstile.py @@ -2,11 +2,13 @@ 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.common.exceptions import TimeoutException import os from twocaptcha import TwoCaptcha # Description: -# In this example, you will learn how to bypass the Cloudflare Turnstile CAPTCHA located on the page https://2captcha.com/demo/cloudflare-turnstile. This demonstration will guide you through the steps of interacting with and overcoming the CAPTCHA using specific techniques +# In this example, you will learn how to bypass the Cloudflare Turnstile CAPTCHA located on the page https://2captcha.com/demo/cloudflare-turnstile. +# This demonstration will guide you through the steps of interacting with and overcoming the CAPTCHA using specific techniques # The value of the `sitekey` parameter is extracted from the page code automaticly. # CONFIGURATION @@ -14,6 +16,7 @@ url = "https://2captcha.com/demo/cloudflare-turnstile" apikey = os.getenv('APIKEY_2CAPTCHA') +solver = TwoCaptcha(apikey) # LOCATORS @@ -25,10 +28,14 @@ # GETTERS -def get_element(locator): +def get_clickable_element(locator): """Waits for an element to be clickable and returns it""" return WebDriverWait(browser, 30).until(EC.element_to_be_clickable((By.XPATH, locator))) +def get_present_element(locator): + """Waits for an element to be present and returns it""" + return WebDriverWait(browser, 30).until(EC.presence_of_element_located((By.XPATH, locator))) + # ACTIONS @@ -41,27 +48,25 @@ def get_sitekey(locator): Returns: str: The sitekey value. """ - sitekey_element = get_element(locator) + sitekey_element = get_present_element(locator) sitekey = sitekey_element.get_attribute('data-sitekey') print(f"Sitekey received: {sitekey}") return sitekey -def solver_captcha(apikey, sitekey, url): +def solver_captcha(sitekey, url): """ Solves the Claudflare Turnstile using the 2Captcha service. Args: - apikey (str): The 2Captcha API key. sitekey (str): The sitekey for the captcha. url (str): The URL where the captcha is located. Returns: - str: The solved captcha code. + dict: The captcha id and the solved captcha code. """ - solver = TwoCaptcha(apikey) try: result = solver.turnstile(sitekey=sitekey, url=url) - print(f"Captcha solved") - return result['code'] + print(f"Captcha solved. Token: {result['code']}.") + return result except Exception as e: print(f"An error occurred: {e}") return None @@ -90,40 +95,69 @@ def click_check_button(locator): Args: locator (str): The XPath locator of the check button. """ - get_element(locator).click() + get_clickable_element(locator).click() print("Pressed the Check button") -def final_message(locator): +def final_message_and_report(locator, id): """ - Retrieves and prints the final success message. + Retrieves and prints the final success message and sends a report to 2Captcha. + + Submitting answer reports is not necessary to solve the captcha. But it can help you reduce the cost of the solution + and improve accuracy. We have described why it is important to submit reports in our blog: + https://2captcha.com/ru/blog/reportgood-reportbad + + We recommend reporting both incorrect and correct answers. Args: locator (str): The XPath locator of the success message. + id (str): The captcha id for reporting. """ - message = get_element(locator).text - print(message) + try: + # Check for success message + message = get_present_element(locator).text + print(message) + is_success = True + + except TimeoutException: + # If the element is not found within the timeout + print("Timed out waiting for success message element") + is_success = False + except Exception as e: + # If another error occurs + print(f"Error retrieving final message: {e}") + is_success = False + + # Send the report anyway + solver.report(id, is_success) + print(f"Report sent for id: {id}, success: {is_success}") # MAIN LOGIC with webdriver.Chrome() as browser: - browser.get(url) print('Started') + # Getting a site key sitekey = get_sitekey(sitekey_locator) - token = solver_captcha(apikey, sitekey, url) - - if token: - - send_token(css_locator_for_input_send_token, token) - - click_check_button(submit_button_captcha_locator) - - final_message(success_message_locator) - - print("Finished") + if sitekey: + # Sent captcha to the solution in 2captcha API + result = solver_captcha(sitekey, url) + + if result: + # From the response from the service we get the captcha id and token + id, token = result['captchaId'], result['code'] + # Applying the token on the page + send_token(css_locator_for_input_send_token, token) + # Checking whether the token has been accepted + click_check_button(submit_button_captcha_locator) + # We check if there is a message about the successful solution of the captcha and send a report on the result + # using the captcha id + final_message_and_report(success_message_locator, id) + print("Finished") + else: + print("Failed to solve captcha") else: - print("Failed to solve captcha") + print("Failed to intercept parameters") diff --git a/examples/coordinates/coordinates.py b/examples/coordinates/coordinates.py index 1c9cb99..21181bb 100644 --- a/examples/coordinates/coordinates.py +++ b/examples/coordinates/coordinates.py @@ -2,6 +2,7 @@ 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.common.exceptions import TimeoutException from selenium.webdriver.common.action_chains import ActionChains import os from twocaptcha import TwoCaptcha @@ -12,6 +13,7 @@ url = "https://2captcha.com/demo/clickcaptcha" apikey = os.getenv('APIKEY_2CAPTCHA') +solver = TwoCaptcha(apikey) # LOCATORS @@ -23,28 +25,30 @@ # GETTERS -def get_element(locator): +def get_clickable_element(locator): """Waits for an element to be clickable and returns it""" return WebDriverWait(browser, 30).until(EC.element_to_be_clickable((By.XPATH, locator))) +def get_present_element(locator): + """Waits for an element to be present and returns it""" + return WebDriverWait(browser, 30).until(EC.presence_of_element_located((By.XPATH, locator))) + # ACTIONS -def solver_captcha(image, apikey): +def solver_captcha(image): """ - Solves a captcha using the 2Captcha service and returns the solution code + Solves captcha using the 2captcha service and returns the coordinates of points in the image Args: - image (str): Path to the captcha image - apikey (str): API key to access the 2Captcha service + image (str): Path to the captcha image. Returns: - str: Captcha solution code, if successful, otherwise None + dict: The captcha id and the solved captcha code. """ - solver = TwoCaptcha(apikey) try: result = solver.coordinates(image) - print(f"Captcha solved. Coordinates received") - return result['code'] + print(f"Captcha solved. Token: {result['code']}.") + return result except Exception as e: print(f"An error occurred: {e}") return None @@ -111,7 +115,7 @@ def clicks_on_coordinates(coordinates_list, img_locator_captcha): """ action = ActionChains(browser) - img_element = get_element(img_locator_captcha) + img_element = get_clickable_element(img_locator_captcha) # Getting the initial coordinates of the image element location = img_element.location @@ -138,44 +142,68 @@ def click_check_button(locator): Args: locator (str): XPATH locator of the captcha verification button """ - button = get_element(locator) + button = get_clickable_element(locator) button.click() print("Pressed the Check button") -def final_message(locator): +def final_message_and_report(locator, id): """ - Retrieves and prints the final success message. + Retrieves and prints the final success message and sends a report to 2Captcha. + + Submitting answer reports is not necessary to solve the captcha. But it can help you reduce the cost of the solution + and improve accuracy. We have described why it is important to submit reports in our blog: + https://2captcha.com/ru/blog/reportgood-reportbad + + We recommend reporting both incorrect and correct answers. Args: locator (str): The XPath locator of the success message. + id (str): The captcha id for reporting. """ - message = get_element(locator).text - print(message) + try: + # Check for success message + message = get_present_element(locator).text + print(message) + is_success = True + + except TimeoutException: + # If the element is not found within the timeout + print("Timed out waiting for success message element") + is_success = False + except Exception as e: + # If another error occurs + print(f"Error retrieving final message: {e}") + is_success = False + + # Send the report anyway + solver.report(id, is_success) + print(f"Report sent for id: {id}, success: {is_success}") # MAIN LOGIC # Automatically closes the browser after block execution completes with webdriver.Chrome() as browser: - # Go to page with captcha browser.get(url) print("Started") - # Getting captcha image in base64 format + # Getting captcha image image_base64 = get_image_canvas(img_locator_captcha_for_get) + # Sent captcha to the solution in 2captcha API + result = solver_captcha(image_base64) - answer_to_captcha = solver_captcha(image_base64, apikey) - - if answer_to_captcha: - + if result: + # From the response from the service we get the captcha id and an answer + id, answer_to_captcha = result['captchaId'], result['code'] + # Parse the response and get a list of coordinates coordinates_list = pars_coordinates(answer_to_captcha) - + # Сlicks on the coordinates clicks_on_coordinates(coordinates_list, img_locator_captcha_for_click) - + # Check if the answer is accepted click_check_button(submit_button_captcha_locator) + # We check if there is a message about the successful solution of the captcha and send a report on the result + # using the captcha id + final_message_and_report(success_message_locator, id) - final_message(success_message_locator) - - browser.implicitly_wait(5) print("Finished") else: print("Failed to solve captcha") \ No newline at end of file diff --git a/examples/hCaptcha/hcaptcha.py b/examples/hCaptcha/hcaptcha.py index 9544df4..2ed5b6a 100644 --- a/examples/hCaptcha/hcaptcha.py +++ b/examples/hCaptcha/hcaptcha.py @@ -2,6 +2,7 @@ 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.common.exceptions import TimeoutException from urllib.parse import urlparse, parse_qs import os from twocaptcha import TwoCaptcha @@ -12,6 +13,7 @@ url = "https://2captcha.com/demo/hcaptcha" apikey = os.getenv('APIKEY_2CAPTCHA') +solver = TwoCaptcha(apikey) # LOCATORS @@ -22,10 +24,14 @@ # GETTERS -def get_element(locator): +def get_clickable_element(locator): """Waits for an element to be clickable and returns it""" return WebDriverWait(browser, 30).until(EC.element_to_be_clickable((By.XPATH, locator))) +def get_present_element(locator): + """Waits for an element to be present and returns it""" + return WebDriverWait(browser, 30).until(EC.presence_of_element_located((By.XPATH, locator))) + # ACTIONS @@ -38,30 +44,33 @@ def get_sitekey(locator): Returns: str: The sitekey value. """ - iframe_element = get_element(locator) + # Switch to the iframe using its XPath locator + iframe_element = get_present_element(locator) + # Get the iframe's URL from the 'src' attribute url = iframe_element.get_attribute('src') + # Parse the URL to get different components parsed_url = urlparse(url) + # Extract the sitekey from the URL fragment params = parse_qs(parsed_url.fragment) sitekey = params.get('sitekey', [None])[0] + # Print the received sitekey for debugging print(f"Sitekey received: {sitekey}") return sitekey -def solver_captcha(apikey, sitekey, url): +def solver_captcha(sitekey, url): """ Solves the hCaptcha using the 2Captcha service. Args: - apikey (str): The 2Captcha API key. sitekey (str): The sitekey for the captcha. url (str): The URL where the captcha is located. Returns: - str: The solved captcha code, or None if an error occurred. + dict: The captcha id and the solved captcha code. """ - solver = TwoCaptcha(apikey) try: result = solver.hcaptcha(sitekey=sitekey, url=url) - print(f"Captcha solved") - return result['code'] + print(f"Captcha solved. Token: {result['code']}.") + return result except Exception as e: print(f"An error occurred: {e}") return None @@ -87,44 +96,71 @@ def click_check_button(locator): Args: locator (str): The XPath locator of the check button. """ - get_element(locator).click() + get_clickable_element(locator).click() print("Pressed the Check button") -def final_message(locator): +def final_message_and_report(locator, id): """ - Retrieves and prints the final success message. + Retrieves and prints the final success message and sends a report to 2Captcha. + + Submitting answer reports is not necessary to solve the captcha. But it can help you reduce the cost of the solution + and improve accuracy. We have described why it is important to submit reports in our blog: + https://2captcha.com/ru/blog/reportgood-reportbad + + We recommend reporting both incorrect and correct answers. Args: locator (str): The XPath locator of the success message. + id (str): The captcha id for reporting. """ - message = get_element(locator).text - print(message) + try: + # Check for success message + message = get_present_element(locator).text + print(message) + is_success = True + + except TimeoutException: + # If the element is not found within the timeout + print("Timed out waiting for success message element") + is_success = False + except Exception as e: + # If another error occurs + print(f"Error retrieving final message: {e}") + is_success = False + + # Send the report anyway + solver.report(id, is_success) + print(f"Report sent for id: {id}, success: {is_success}") # MAIN LOGIC # Automatically closes the browser after block execution completes with webdriver.Chrome() as browser: - # Go to the specified URL browser.get(url) print("Started") - # Getting sitekey from iframe + # Getting a site key sitekey = get_sitekey(iframe_locator) - # Solving the captcha and receiving a token - token = solver_captcha(apikey, sitekey, url) - - if token: - # Sending solved captcha token - send_token(token) - # Pressing the Check button - click_check_button(submit_button_captcha_locator) - # Receiving and displaying a success message - final_message(success_message_locator) - - browser.implicitly_wait(5) - print("Finished") + + if sitekey: + # Sent captcha to the solution in 2captcha API + result = solver_captcha(sitekey, url) + + if result: + # From the response from the service we get the captcha id and token + id, token = result['captchaId'], result['code'] + # Applying the token on the page + send_token(token) + # Checking whether the token has been accepted + click_check_button(submit_button_captcha_locator) + # We check if there is a message about the successful solution of the captcha and send a report on the result + # using the captcha id + final_message_and_report(success_message_locator, id) + print("Finished") + else: + print("Failed to solve captcha") else: - print("Failed to solve captcha") + print("Sitekey not found") diff --git a/examples/hCaptcha/hcaptcha_proxy.py b/examples/hCaptcha/hcaptcha_proxy.py index 4eab99e..d83875a 100644 --- a/examples/hCaptcha/hcaptcha_proxy.py +++ b/examples/hCaptcha/hcaptcha_proxy.py @@ -3,6 +3,7 @@ from selenium.webdriver.support.wait import WebDriverWait from selenium.webdriver.chrome.options import Options from selenium.webdriver.support import expected_conditions as EC +from selenium.common.exceptions import TimeoutException from urllib.parse import urlparse, parse_qs from webdriver_manager.chrome import ChromeDriverManager from selenium.webdriver.chrome.service import Service @@ -18,6 +19,7 @@ proxy = {'type': 'HTTP', 'uri': 'username:password@ip:port'} +solver = TwoCaptcha(apikey) # LOCATORS @@ -28,10 +30,14 @@ # GETTERS -def get_element(locator): +def get_clickable_element(locator): """Waits for an element to be clickable and returns it""" return WebDriverWait(browser, 30).until(EC.element_to_be_clickable((By.XPATH, locator))) +def get_present_element(locator): + """Waits for an element to be present and returns it""" + return WebDriverWait(browser, 30).until(EC.presence_of_element_located((By.XPATH, locator))) + # ACTIONS @@ -44,10 +50,15 @@ def parse_proxy_uri(proxy): Returns: tuple: A tuple containing scheme, login, password, IP, and port. """ + # Extract proxy type and convert to lowercase scheme = proxy['type'].lower + # Split URI into authentication info and address (IP:port) auth, address = proxy['uri'].split('@') + # Extract login and password from auth login, password = auth.split(':') + # Extract IP and port from address ip, port = address.split(':') + # Return extracted proxy details return scheme, login, password, ip, port def setup_proxy(proxy): @@ -60,35 +71,64 @@ def setup_proxy(proxy): Returns: Options: Configured Chrome options with proxy settings. """ + # Initialize Chrome options to modify default Chrome behavior chrome_options = webdriver.ChromeOptions() + # Extract proxy details (scheme, username, password, IP, port) scheme, username, password, ip, port = parse_proxy_uri(proxy) + # Create a proxy extension with the extracted credentials proxies_extension = proxies(scheme, username, password, ip, port) + # Add proxy extension to Chrome options chrome_options.add_extension(proxies_extension) + # Return the configured Chrome options return chrome_options def get_sitekey(locator): - """Extracts the sitekey from the iframe's URL""" - iframe_element = get_element(locator) + """ + Extracts the sitekey from the iframe's URL. + + Args: + locator (str): The XPath locator of the iframe element. + Returns: + str: The sitekey value. + """ + # Switch to the iframe using its XPath locator + iframe_element = get_clickable_element(locator) + # Get the iframe's URL from the 'src' attribute url = iframe_element.get_attribute('src') + # Parse the URL to get different components parsed_url = urlparse(url) + # Extract the sitekey from the URL fragment params = parse_qs(parsed_url.fragment) sitekey = params.get('sitekey', [None])[0] + # Print the received sitekey for debugging print(f"Sitekey received: {sitekey}") return sitekey -def solver_captcha(apikey, sitekey, url, proxy): - """Solves the hCaptcha using the 2Captcha service""" - solver = TwoCaptcha(apikey) +def solver_captcha(sitekey, url, proxy): + """ + Solves the hCaptcha using the 2Captcha service. + + Args: + sitekey (str): The sitekey for the captcha. + url (str): The URL where the captcha is located. + Returns: + dict: The captcha id and the solved captcha code. + """ try: result = solver.hcaptcha(sitekey=sitekey, url=url, proxy=proxy) - print(f"Captcha solved") - return result['code'] + print(f"Captcha solved. Token: {result['code']}.") + return result except Exception as e: print(f"An error occurred: {e}") return None def send_token(captcha_token): - """Sends the captcha token to the hCaptcha iframe and response field""" + """ + Sends the captcha token to the hCaptcha iframe and response field. + + Args: + captcha_token (str): The solved captcha token. + """ script = f""" document.querySelector('iframe[src*=\\"hcaptcha\\"]').setAttribute('data-hcaptcha-response', '{captcha_token}'); document.querySelector('[name="h-captcha-response"]').innerText = '{captcha_token}'; @@ -97,14 +137,47 @@ def send_token(captcha_token): print("Token sent") def click_check_button(locator): - """Clicks the captcha check button""" - get_element(locator).click() + """ + Clicks the captcha check button. + + Args: + locator (str): The XPath locator of the check button. + """ + get_clickable_element(locator).click() print("Pressed the Check button") -def final_message(locator): - """Retrieves and prints the final success message""" - message = get_element(locator).text - print(message) +def final_message_and_report(locator, id): + """ + Retrieves and prints the final success message and sends a report to 2Captcha. + + Submitting answer reports is not necessary to solve the captcha. But it can help you reduce the cost of the solution + and improve accuracy. We have described why it is important to submit reports in our blog: + https://2captcha.com/ru/blog/reportgood-reportbad + + We recommend reporting both incorrect and correct answers. + + Args: + locator (str): The XPath locator of the success message. + id (str): The captcha id for reporting. + """ + try: + # Check for success message + message = get_present_element(locator).text + print(message) + is_success = True + + except TimeoutException: + # If the element is not found within the timeout + print("Timed out waiting for success message element") + is_success = False + except Exception as e: + # If another error occurs + print(f"Error retrieving final message: {e}") + is_success = False + + # Send the report anyway + solver.report(id, is_success) + print(f"Report sent for id: {id}, success: {is_success}") # MAIN LOGIC @@ -114,26 +187,30 @@ def final_message(locator): # Automatically closes the browser after block execution completes with webdriver.Chrome(service=Service(ChromeDriverManager().install()), options=chrome_options) as browser: - # Go to the specified URL browser.get(url) print("Started") - # Getting sitekey from iframe + # Getting a site key sitekey = get_sitekey(iframe_locator) - # Solving the captcha and receiving a token - token = solver_captcha(apikey, sitekey, url, proxy) - - if token: - # Sending solved captcha token - send_token(token) - # Pressing the Check button - click_check_button(submit_button_captcha_locator) - # Receiving and displaying a success message - final_message(success_message_locator) - - browser.implicitly_wait(5) - print("Finished") + + if sitekey: + # Sent captcha to the solution in 2captcha API + result = solver_captcha(sitekey, url, proxy) + + if result: + # From the response from the service we get the captcha id and token + id, token = result['captchaId'], result['code'] + # Applying the token on the page + send_token(token) + # Checking whether the token has been accepted + click_check_button(submit_button_captcha_locator) + # We check if there is a message about the successful solution of the captcha and send a report on the result + # using the captcha id + final_message_and_report(success_message_locator, id) + print("Finished") + else: + print("Failed to solve captcha") else: - print("Failed to solve captcha") + print("Sitekey not found") diff --git a/examples/mtcaptcha/mtcaptcha.py b/examples/mtcaptcha/mtcaptcha.py index 5853034..4dc391b 100644 --- a/examples/mtcaptcha/mtcaptcha.py +++ b/examples/mtcaptcha/mtcaptcha.py @@ -2,6 +2,7 @@ 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.common.exceptions import TimeoutException import os import time from twocaptcha import TwoCaptcha @@ -12,6 +13,8 @@ url = "https://2captcha.com/demo/mtcaptcha" apikey = os.getenv('APIKEY_2CAPTCHA') +solver = TwoCaptcha(apikey) + # LOCATORS @@ -22,10 +25,14 @@ # GETTERS -def get_element(locator): +def get_clickable_element(locator): """Waits for an element to be clickable and returns it""" return WebDriverWait(browser, 30).until(EC.element_to_be_clickable((By.XPATH, locator))) +def get_present_element(locator): + """Waits for an element to be present and returns it""" + return WebDriverWait(browser, 30).until(EC.presence_of_element_located((By.XPATH, locator))) + # ACTIONS @@ -44,22 +51,20 @@ def get_sitekey(): print("Sitekey received") return sitekey -def solver_captcha(apikey, sitekey, url): +def solver_captcha(sitekey, url): """ Solves the MTCaptcha using the 2Captcha service. Args: - apikey (str): The 2Captcha API key. sitekey (str): The sitekey for the captcha. url (str): The URL where the captcha is located. Returns: - str: The solved captcha code. + dict: The captcha id and the solved captcha code. """ - solver = TwoCaptcha(apikey) try: result = solver.mtcaptcha(sitekey=sitekey, url=url) - print(f"Captcha solved") - return result['code'] + print(f"Captcha solved. Answer: {result['code']}.") + return result except Exception as e: print(f"An error occurred: {e}") return None @@ -88,19 +93,41 @@ def click_check_button(locator): Args: locator (str): The XPath locator of the check button. """ - get_element(locator).click() + get_clickable_element(locator).click() print("Pressed the Check button") -def final_message(locator): +def final_message_and_report(locator, id): """ - Retrieves and prints the final success message. + Retrieves and prints the final success message and sends a report to 2Captcha. + + Submitting answer reports is not necessary to solve the captcha. But it can help you reduce the cost of the solution + and improve accuracy. We have described why it is important to submit reports in our blog: + https://2captcha.com/ru/blog/reportgood-reportbad + + We recommend reporting both incorrect and correct answers. Args: locator (str): The XPath locator of the success message. + id (str): The captcha id for reporting. """ - message = get_element(locator).text - print(message) + try: + # Check for success message + message = get_present_element(locator).text + print(message) + is_success = True + + except TimeoutException: + # If the element is not found within the timeout + print("Timed out waiting for success message element") + is_success = False + except Exception as e: + # If another error occurs + print(f"Error retrieving final message: {e}") + is_success = False + # Send the report anyway + solver.report(id, is_success) + print(f"Report sent for id: {id}, success: {is_success}") # MAIN LOGIC @@ -109,21 +136,28 @@ def final_message(locator): browser.get(url) print("Started") + # Getting a site key sitekey = get_sitekey() - token = solver_captcha(apikey, sitekey, url) - - if token: - - send_token(css_locator_for_input_send_token, token) - - click_check_button(submit_button_captcha_locator) - - final_message(success_message_locator) - - print("Finished") + if sitekey: + # Sent captcha to the solution in 2captcha API + result = solver_captcha(sitekey, url) + + if result: + # From the response from the service we get the captcha id and token + id, token = result['captchaId'], result['code'] + # Applying the token on the page + send_token(css_locator_for_input_send_token, token) + # Checking whether the token has been accepted + click_check_button(submit_button_captcha_locator) + # We check if there is a message about the successful solution of the captcha and send a report on the result + # using the captcha id + final_message_and_report(success_message_locator, id) + print("Finished") + else: + print("Failed to solve captcha") else: - print("Failed to solve captcha") + print("Sitekey not found") diff --git a/examples/normal_captcha/normal_captcha_canvas.py b/examples/normal_captcha/normal_captcha_canvas.py index 31ef54e..5f1e8e1 100644 --- a/examples/normal_captcha/normal_captcha_canvas.py +++ b/examples/normal_captcha/normal_captcha_canvas.py @@ -2,6 +2,7 @@ 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.common.exceptions import TimeoutException import os from twocaptcha import TwoCaptcha @@ -11,6 +12,7 @@ url = "https://2captcha.com/demo/normal" apikey = os.getenv('APIKEY_2CAPTCHA') +solver = TwoCaptcha(apikey) # LOCATORS @@ -22,35 +24,30 @@ # GETTERS -def get_locator(locator): - """ - Waits for the element specified by the locator to become clickable and returns its web element - - Args: - locator (str): XPATH locator to find an element on the page - Returns: - WebElement: A web element that has become clickable - """ +def get_clickable_element(locator): + """Waits for an element to be clickable and returns it""" return WebDriverWait(browser, 30).until(EC.element_to_be_clickable((By.XPATH, locator))) +def get_present_element(locator): + """Waits for an element to be present and returns it""" + return WebDriverWait(browser, 30).until(EC.presence_of_element_located((By.XPATH, locator))) + # ACTIONS -def solver_captcha(image, apikey): +def solver_captcha(image): """ Solves a captcha using the 2Captcha service and returns the solution code Args: image (str): Path to the captcha image - apikey (str): API key to access the 2Captcha service Returns: - str: Captcha solution code, if successful, otherwise None + dict: The captcha id and the solved captcha code. """ - solver = TwoCaptcha(apikey) try: result = solver.normal(image) - print(f"Captcha solved. Code: {result['code']}") - return result['code'] + print(f"Captcha solved. Answer: {result['code']}.") + return result except Exception as e: print(f"An error occurred: {e}") return None @@ -89,7 +86,7 @@ def input_captcha_code(locator, code): locator (str): XPATH locator of the captcha input field code (str): Captcha solution code """ - input_field = get_locator(locator) + input_field = get_clickable_element(locator) input_field.send_keys(code) print("Entered the answer to the captcha") @@ -100,42 +97,66 @@ def click_check_button(locator): Args: locator (str): XPATH locator of the captcha verification button """ - button = get_locator(locator) + button = get_clickable_element(locator) button.click() print("Pressed the Check button") -def final_message(locator): +def final_message_and_report(locator, id): """ - Retrieves and prints the final success message. + Retrieves and prints the final success message and sends a report to 2Captcha. + + Submitting answer reports is not necessary to solve the captcha. But it can help you reduce the cost of the solution + and improve accuracy. We have described why it is important to submit reports in our blog: + https://2captcha.com/ru/blog/reportgood-reportbad + + We recommend reporting both incorrect and correct answers. Args: locator (str): The XPath locator of the success message. + id (str): The captcha id for reporting. """ - message = get_locator(locator).text - print(message) + try: + # Check for success message + message = get_present_element(locator).text + print(message) + is_success = True + + except TimeoutException: + # If the element is not found within the timeout + print("Timed out waiting for success message element") + is_success = False + except Exception as e: + # If another error occurs + print(f"Error retrieving final message: {e}") + is_success = False + + # Send the report anyway + solver.report(id, is_success) + print(f"Report sent for id: {id}, success: {is_success}") # MAIN LOGIC # Automatically closes the browser after block execution completes with webdriver.Chrome() as browser: - # Go to page with captcha browser.get(url) print("Started") - # Getting captcha image in base64 format + # Getting captcha image image_base64 = get_image_canvas(img_locator) + # Sent captcha to the solution in 2captcha API + result = solver_captcha(image_base64) - # Solving captcha using 2Captcha - code = solver_captcha(image_base64, apikey) - - if code: - # Entering captcha code + if result: + # From the response from the service we get the captcha id and an answer + id, code = result['captchaId'], result['code'] + # Sending an answer input_captcha_code(input_captcha_locator, code) - # Pressing the test button + # Check if the answer is accepted click_check_button(submit_button_captcha_locator) - # Receiving and displaying a success message - final_message(success_message_locator) + # We check if there is a message about the successful solution of the captcha and send a report on the result + # using the captcha id + final_message_and_report(success_message_locator, id) browser.implicitly_wait(5) else: diff --git a/examples/normal_captcha/normal_captcha_screenshot.py b/examples/normal_captcha/normal_captcha_screenshot.py index 0f61fce..4c610fe 100644 --- a/examples/normal_captcha/normal_captcha_screenshot.py +++ b/examples/normal_captcha/normal_captcha_screenshot.py @@ -2,6 +2,7 @@ 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.common.exceptions import TimeoutException import os from twocaptcha import TwoCaptcha @@ -11,6 +12,7 @@ url = "https://2captcha.com/demo/normal" apikey = os.getenv('APIKEY_2CAPTCHA') +solver = TwoCaptcha(apikey) # LOCATORS @@ -22,28 +24,30 @@ # GETTERS -def get_element(locator): +def get_clickable_element(locator): """Waits for an element to be clickable and returns it""" return WebDriverWait(browser, 30).until(EC.element_to_be_clickable((By.XPATH, locator))) +def get_present_element(locator): + """Waits for an element to be present and returns it""" + return WebDriverWait(browser, 30).until(EC.presence_of_element_located((By.XPATH, locator))) + # ACTIONS -def solver_captcha(image, apikey): +def solver_captcha(image): """ Solves a captcha using the 2Captcha service and returns the solution code Args: image (str): Path to the captcha image - apikey (str): API key to access the 2Captcha service Returns: - str: Captcha solution code, if successful, otherwise None + dict: The captcha id and the solved captcha code. """ - solver = TwoCaptcha(apikey) try: result = solver.normal(image) - print(f"Captcha solved. Code: {result['code']}") - return result['code'] + print(f"Captcha solved. Answer: {result['code']}.") + return result except Exception as e: print(f"An error occurred: {e}") return None @@ -57,7 +61,7 @@ def get_image_base64(locator): Returns: str: The base64-encoded screenshot of the image element. """ - image_element = get_element(locator) + image_element = get_present_element(locator) base64_image = image_element.screenshot_as_base64 return base64_image @@ -68,7 +72,7 @@ def input_captcha_code(locator, code): locator (str): XPATH locator of the captcha input field code (str): Captcha solution code """ - input_field = get_element(locator) + input_field = get_clickable_element(locator) input_field.send_keys(code) print("Entered the answer to the captcha") @@ -78,42 +82,66 @@ def click_check_button(locator): Args: locator (str): XPATH locator of the captcha verification button """ - button = get_element(locator) + button = get_clickable_element(locator) button.click() print("Pressed the Check button") -def final_message(locator): +def final_message_and_report(locator, id): """ - Retrieves and prints the final success message. + Retrieves and prints the final success message and sends a report to 2Captcha. + + Submitting answer reports is not necessary to solve the captcha. But it can help you reduce the cost of the solution + and improve accuracy. We have described why it is important to submit reports in our blog: + https://2captcha.com/ru/blog/reportgood-reportbad + + We recommend reporting both incorrect and correct answers. Args: locator (str): The XPath locator of the success message. + id (str): The captcha id for reporting. """ - message = get_element(locator).text - print(message) + try: + # Check for success message + message = get_present_element(locator).text + print(message) + is_success = True + + except TimeoutException: + # If the element is not found within the timeout + print("Timed out waiting for success message element") + is_success = False + except Exception as e: + # If another error occurs + print(f"Error retrieving final message: {e}") + is_success = False + + # Send the report anyway + solver.report(id, is_success) + print(f"Report sent for id: {id}, success: {is_success}") # MAIN LOGIC # Automatically closes the browser after block execution completes with webdriver.Chrome() as browser: - # Go to page with captcha browser.get(url) print("Started") - # Getting captcha image in base64 format + # Getting captcha image image_base64 = get_image_base64(img_locator) + # Sent captcha to the solution in 2captcha API + result = solver_captcha(image_base64) - # Solving captcha using 2Captcha - code = solver_captcha(image_base64, apikey) - - if code: - # Entering captcha code + if result: + # From the response from the service we get the captcha id and an answer + id, code = result['captchaId'], result['code'] + # Sending an answer input_captcha_code(input_captcha_locator, code) - # Pressing the test button + # Check if the answer is accepted click_check_button(submit_button_captcha_locator) - # Receiving and displaying a success message - final_message(success_message_locator) + # We check if there is a message about the successful solution of the captcha and send a report on the result + # using the captcha id + final_message_and_report(success_message_locator, id) browser.implicitly_wait(5) print("Finished") diff --git a/examples/normal_captcha/normal_captcha_screenshot_params.py b/examples/normal_captcha/normal_captcha_screenshot_params.py index 95aa61b..a3ef1c8 100644 --- a/examples/normal_captcha/normal_captcha_screenshot_params.py +++ b/examples/normal_captcha/normal_captcha_screenshot_params.py @@ -2,6 +2,7 @@ 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.common.exceptions import TimeoutException import os from twocaptcha import TwoCaptcha @@ -11,6 +12,7 @@ url = "https://2captcha.com/demo/normal" apikey = os.getenv('APIKEY_2CAPTCHA') +solver = TwoCaptcha(apikey) # ADVANCED CAPTCHA OPTIONS @@ -32,28 +34,30 @@ # GETTERS -def get_element(locator): +def get_clickable_element(locator): """Waits for an element to be clickable and returns it""" return WebDriverWait(browser, 30).until(EC.element_to_be_clickable((By.XPATH, locator))) +def get_present_element(locator): + """Waits for an element to be present and returns it""" + return WebDriverWait(browser, 30).until(EC.presence_of_element_located((By.XPATH, locator))) + # ACTIONS -def solver_captcha(image, apikey, **extra_options): +def solver_captcha(image, **extra_options): """ Solves a captcha using the 2Captcha service and returns the solution code Args: image (str): Path to the captcha image - apikey (str): API key to access the 2Captcha service Returns: - str: Captcha solution code, if successful, otherwise None + dict: The captcha id and the solved captcha code. """ - solver = TwoCaptcha(apikey) try: result = solver.normal(image, **extra_options) - print(f"Captcha solved. Code: {result['code']}") - return result['code'] + print(f"Captcha solved. Answer: {result['code']}.") + return result except Exception as e: print(f"An error occurred: {e}") return None @@ -67,7 +71,7 @@ def get_image_base64(locator): Returns: str: The base64-encoded screenshot of the image element. """ - image_element = get_element(locator) + image_element = get_present_element(locator) base64_image = image_element.screenshot_as_base64 return base64_image @@ -78,7 +82,7 @@ def input_captcha_code(locator, code): locator (str): XPATH locator of the captcha input field code (str): Captcha solution code """ - input_field = get_element(locator) + input_field = get_clickable_element(locator) input_field.send_keys(code) print("Entered the answer to the captcha") @@ -88,42 +92,67 @@ def click_check_button(locator): Args: locator (str): XPATH locator of the captcha verification button """ - button = get_element(locator) + button = get_clickable_element(locator) button.click() print("Pressed the Check button") -def final_message(locator): +def final_message_and_report(locator, id): """ - Retrieves and prints the final success message. + Retrieves and prints the final success message and sends a report to 2Captcha. + + Submitting answer reports is not necessary to solve the captcha. But it can help you reduce the cost of the solution + and improve accuracy. We have described why it is important to submit reports in our blog: + https://2captcha.com/ru/blog/reportgood-reportbad + + We recommend reporting both incorrect and correct answers. Args: locator (str): The XPath locator of the success message. + id (str): The captcha id for reporting. """ - message = get_element(locator).text - print(message) + try: + # Check for success message + message = get_present_element(locator).text + print(message) + is_success = True + + except TimeoutException: + # If the element is not found within the timeout + print("Timed out waiting for success message element") + is_success = False + except Exception as e: + # If another error occurs + print(f"Error retrieving final message: {e}") + is_success = False + + # Send the report anyway + solver.report(id, is_success) + print(f"Report sent for id: {id}, success: {is_success}") # MAIN LOGIC # Automatically closes the browser after block execution completes with webdriver.Chrome() as browser: - # Go to page with captcha + browser.get(url) print("Started") - # Getting captcha image in base64 format + # Getting captcha image image_base64 = get_image_base64(img_locator) + # Sent captcha to the solution in 2captcha API + result = solver_captcha(image_base64, **extra_options) - # Solving captcha using 2Captcha - code = solver_captcha(image_base64, apikey, **extra_options) - - if code: - # Entering captcha code + if result: + # From the response from the service we get the captcha id and an answer + id, code = result['captchaId'], result['code'] + # Sending an answer input_captcha_code(input_captcha_locator, code) - # Pressing the test button + # Check if the answer is accepted click_check_button(submit_button_captcha_locator) - # Receiving and displaying a success message - final_message(success_message_locator) + # We check if there is a message about the successful solution of the captcha and send a report on the result + # using the captcha id + final_message_and_report(success_message_locator, id) browser.implicitly_wait(5) print("Finished") diff --git a/examples/reCAPTCHA/recaptcha_v2.py b/examples/reCAPTCHA/recaptcha_v2.py index 917b93d..4e2359d 100644 --- a/examples/reCAPTCHA/recaptcha_v2.py +++ b/examples/reCAPTCHA/recaptcha_v2.py @@ -2,6 +2,7 @@ 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.common.exceptions import TimeoutException import os from twocaptcha import TwoCaptcha @@ -11,6 +12,7 @@ url = "https://2captcha.com/demo/recaptcha-v2" apikey = os.getenv('APIKEY_2CAPTCHA') +solver = TwoCaptcha(apikey) # LOCATORS @@ -21,10 +23,14 @@ # GETTERS -def get_element(locator): +def get_clickable_element(locator): """Waits for an element to be clickable and returns it""" return WebDriverWait(browser, 30).until(EC.element_to_be_clickable((By.XPATH, locator))) +def get_present_element(locator): + """Waits for an element to be present and returns it""" + return WebDriverWait(browser, 30).until(EC.presence_of_element_located((By.XPATH, locator))) + # ACTIONS @@ -37,29 +43,27 @@ def get_sitekey(locator): Returns: str: The sitekey value. """ - sitekey_element = get_element(locator) + sitekey_element = get_present_element(locator) sitekey = sitekey_element.get_attribute('data-sitekey') - print(f"Sitekey received: {sitekey}") + print(f"Sitekey received: {sitekey}.") return sitekey -def solver_captcha(apikey, sitekey, url): +def solver_captcha(sitekey, url): """ Solves the reCaptcha using the 2Captcha service. Args: - apikey (str): The 2Captcha API key. sitekey (str): The sitekey for the captcha. url (str): The URL where the captcha is located. Returns: - str: The solved captcha code. + dict: The captcha id and the solved captcha code. """ - solver = TwoCaptcha(apikey) try: result = solver.recaptcha(sitekey=sitekey, url=url) - print(f"Captcha solved") - return result['code'] + print(f"Captcha solved. Token: {result['code']}.") + return result except Exception as e: - print(f"An error occurred: {e}") + print(f"An error occurred: {e}.") return None def send_token(captcha_token): @@ -73,7 +77,7 @@ def send_token(captcha_token): document.querySelector('[id="g-recaptcha-response"]').innerText = '{captcha_token}'; """ browser.execute_script(script) - print("Token sent") + print("Token sent.") def click_check_button(locator): """ @@ -82,43 +86,67 @@ def click_check_button(locator): Args: locator (str): The XPath locator of the check button. """ - get_element(locator).click() - print("Pressed the Check button") + get_clickable_element(locator).click() + print("Pressed the Check button.") -def final_message(locator): +def final_message_and_report(locator, id): """ - Retrieves and prints the final success message. + Retrieves and prints the final success message and sends a report to 2Captcha. + + Submitting answer reports is not necessary to solve the captcha. But it can help you reduce the cost of the solution + and improve accuracy. We have described why it is important to submit reports in our blog: + https://2captcha.com/ru/blog/reportgood-reportbad + + We recommend reporting both incorrect and correct answers. Args: locator (str): The XPath locator of the success message. + id (str): The captcha id for reporting. """ - message = get_element(locator).text - print(message) + try: + # Check for success message + message = get_present_element(locator).text + print(message) + is_success = True + + except TimeoutException: + # If the element is not found within the timeout + print("Timed out waiting for success message element.") + is_success = False + except Exception as e: + # If another error occurs + print(f"Error retrieving final message: {e}.") + is_success = False + + # Send the report anyway + solver.report(id, is_success) + print(f"Report sent for id: {id}, success: {is_success}.") # MAIN LOGIC with webdriver.Chrome() as browser: - # Go to the specified URL browser.get(url) - print('Started') + print('Started.') - # Getting sitekey from the sitekey element + # Getting a site key sitekey = get_sitekey(sitekey_locator) - # Solving the captcha and receiving a token - token = solver_captcha(apikey, sitekey, url) - - if token: - # Sending solved captcha token - send_token(token) - - # Pressing the Check button - click_check_button(submit_button_captcha_locator) - - # Receiving and displaying a success message - final_message(success_message_locator) - - browser.implicitly_wait(5) - print("Finished") + if sitekey: + # Sent captcha to the solution in 2captcha API + result = solver_captcha(sitekey, url) + + if result: + # From the response from the service we get the captcha id and token + id, token = result['captchaId'], result['code'] + # Applying the token on the page + send_token(token) + # Checking whether the token has been accepted + click_check_button(submit_button_captcha_locator) + # We check if there is a message about the successful solution of the captcha and send a report on the result + # using the captcha id + final_message_and_report(success_message_locator, id) + print("Finished.") + else: + print("Failed to solve captcha.") else: - print("Failed to solve captcha") + print("Sitekey not found.") diff --git a/examples/reCAPTCHA/recaptcha_v2_callback_proxy.py b/examples/reCAPTCHA/recaptcha_v2_callback_proxy.py index 8c80266..34c0731 100644 --- a/examples/reCAPTCHA/recaptcha_v2_callback_proxy.py +++ b/examples/reCAPTCHA/recaptcha_v2_callback_proxy.py @@ -2,6 +2,7 @@ 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.common.exceptions import TimeoutException from webdriver_manager.chrome import ChromeDriverManager from selenium.webdriver.chrome.service import Service import os @@ -16,6 +17,8 @@ proxy = {'type': 'HTTPS', 'uri': 'username:password@ip:port'} +solver = TwoCaptcha(apikey) + # JavaScript script to find reCAPTCHA clients and extract sitekey and callback function script = """ function findRecaptchaClients() { @@ -66,9 +69,9 @@ # GETTERS -def get_element(locator): - """Waits for an element to be clickable and returns it""" - return WebDriverWait(browser, 30).until(EC.element_to_be_clickable((By.XPATH, locator))) +def get_present_element(locator): + """Waits for an element to be present and returns it""" + return WebDriverWait(browser, 30).until(EC.presence_of_element_located((By.XPATH, locator))) # ACTIONS @@ -79,13 +82,23 @@ def parse_proxy_uri(proxy): Args: proxy (dict): Dictionary containing the proxy type and URI. + Example: + proxy = { + 'type': 'http', + 'uri': 'username:password@192.168.1.1:8080' + } Returns: tuple: A tuple containing scheme, login, password, IP, and port. """ + # Extract proxy type and convert to lowercase scheme = proxy['type'].lower + # Split URI into authentication info and address (IP:port) auth, address = proxy['uri'].split('@') + # Extract login and password from auth login, password = auth.split(':') + # Extract IP and port from address ip, port = address.split(':') + # Return extracted proxy details return scheme, login, password, ip, port def setup_proxy(proxy): @@ -98,10 +111,15 @@ def setup_proxy(proxy): Returns: Options: Configured Chrome options with proxy settings. """ + # Initialize Chrome options to modify default Chrome behavior chrome_options = webdriver.ChromeOptions() + # Extract proxy details (scheme, username, password, IP, port) scheme, username, password, ip, port = parse_proxy_uri(proxy) + # Create a proxy extension with the extracted credentials proxies_extension = proxies(scheme, username, password, ip, port) + # Add proxy extension to Chrome options chrome_options.add_extension(proxies_extension) + # Return the configured Chrome options return chrome_options def get_captcha_params(script): @@ -119,6 +137,7 @@ def get_captcha_params(script): result = browser.execute_script(script) if not result or not result[0]: raise IndexError("Callback name is empty or null") + # Extract the function name and sitekey callback_function_name = result[0]['function'] sitekey = result[0]['sitekey'] print("Got the callback function name and site key") @@ -127,23 +146,21 @@ def get_captcha_params(script): retries += 1 time.sleep(1) # Wait a bit before retrying -def solver_captcha(apikey, sitekey, url, proxy): +def solver_captcha(sitekey, url, proxy): """ Solves the reCaptcha using the 2Captcha service. Args: - apikey (str): The 2Captcha API key. sitekey (str): The sitekey for the captcha. url (str): The URL where the captcha is located. proxy (dict): Dictionary containing the proxy settings. Returns: - str: The solved captcha code, or None if an error occurred. + dict: The captcha id and the solved captcha code. """ - solver = TwoCaptcha(apikey) try: result = solver.recaptcha(sitekey=sitekey, url=url, proxy=proxy) - print(f"Captcha solved") - return result['code'] + print(f"Captcha solved. Token: {result['code']}.") + return result except Exception as e: print(f"An error occurred: {e}") return None @@ -160,15 +177,38 @@ def send_token_callback(callback_function, token): browser.execute_script(script) print("The token is sent to the callback function") -def final_message(locator): +def final_message_and_report(locator, id): """ - Retrieves and prints the final success message. + Retrieves and prints the final success message and sends a report to 2Captcha. + + Submitting answer reports is not necessary to solve the captcha. But it can help you reduce the cost of the solution + and improve accuracy. We have described why it is important to submit reports in our blog: + https://2captcha.com/ru/blog/reportgood-reportbad + + We recommend reporting both incorrect and correct answers. Args: locator (str): The XPath locator of the success message. + id (str): The captcha id for reporting. """ - message = get_element(locator).text - print(message) + try: + # Check for success message + message = get_present_element(locator).text + print(message) + is_success = True + + except TimeoutException: + # If the element is not found within the timeout + print("Timed out waiting for success message element") + is_success = False + except Exception as e: + # If another error occurs + print(f"Error retrieving final message: {e}") + is_success = False + + # Send the report anyway + solver.report(id, is_success) + print(f"Report sent for id: {id}, success: {is_success}") # MAIN LOGIC @@ -179,20 +219,23 @@ def final_message(locator): browser.get(url) print("Started") - # Extracting callback function name and sitekey using the provided script + # Getting a site key and callback function callback_function, sitekey = get_captcha_params(script) - # Solving the captcha and receiving the token - token = solver_captcha(apikey, sitekey, url, proxy) - - if token: - # Sending the solved captcha token to the callback function - send_token_callback(callback_function, token) - - # Retrieving and printing the final success message - final_message(success_message_locator) - - browser.implicitly_wait(5) - print("Finished") + if sitekey: + # Sent captcha to the solution in 2captcha API + result = solver_captcha(sitekey, url, proxy) + + if result: + # From the response from the service we get the captcha id and token + id, token = result['captchaId'], result['code'] + # Applying the token using the callback function + send_token_callback(callback_function, token) + # We check if there is a message about the successful solution of the captcha and send a report on the result + # using the captcha id + final_message_and_report(success_message_locator, id) + print("Finished") + else: + print("Failed to solve captcha") else: - print("Failed to solve captcha") \ No newline at end of file + print("Sitekey not found") \ No newline at end of file diff --git a/examples/reCAPTCHA/recaptcha_v2_callback_variant1.py b/examples/reCAPTCHA/recaptcha_v2_callback_variant1.py index c3580a3..8c5d9d1 100644 --- a/examples/reCAPTCHA/recaptcha_v2_callback_variant1.py +++ b/examples/reCAPTCHA/recaptcha_v2_callback_variant1.py @@ -2,6 +2,7 @@ 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.common.exceptions import TimeoutException import os from twocaptcha import TwoCaptcha @@ -16,6 +17,7 @@ url = "https://2captcha.com/demo/recaptcha-v2-callback" apikey = os.getenv('APIKEY_2CAPTCHA') +solver = TwoCaptcha(apikey) # LOCATORS @@ -25,9 +27,9 @@ # GETTERS -def get_element(locator): - """Waits for an element to be clickable and returns it""" - return WebDriverWait(browser, 30).until(EC.element_to_be_clickable((By.XPATH, locator))) +def get_present_element(locator): + """Waits for an element to be present and returns it""" + return WebDriverWait(browser, 30).until(EC.presence_of_element_located((By.XPATH, locator))) # ACTIONS @@ -41,27 +43,25 @@ def get_sitekey(locator): Returns: str: The sitekey value. """ - sitekey_element = get_element(locator) + sitekey_element = get_present_element(locator) sitekey = sitekey_element.get_attribute('data-sitekey') print(f"Sitekey received: {sitekey}") return sitekey -def solver_captcha(apikey, sitekey, url): +def solver_captcha(sitekey, url): """ Solves the reCaptcha using the 2Captcha service. Args: - apikey (str): The 2Captcha API key. sitekey (str): The sitekey for the captcha. url (str): The URL where the captcha is located. Returns: - str: The solved captcha code. + dict: The captcha id and the solved captcha code. """ - solver = TwoCaptcha(apikey) try: result = solver.recaptcha(sitekey=sitekey, url=url) - print(f"Captcha solved") - return result['code'] + print(f"Captcha solved. Token: {result['code']}.") + return result except Exception as e: print(f"An error occurred: {e}") return None @@ -73,38 +73,64 @@ def send_token(token): browser.execute_script(script) print("The token is sent to the callback function") -def final_message(locator): +def final_message_and_report(locator, id): """ - Retrieves and prints the final success message. + Retrieves and prints the final success message and sends a report to 2Captcha. + + Submitting answer reports is not necessary to solve the captcha. But it can help you reduce the cost of the solution + and improve accuracy. We have described why it is important to submit reports in our blog: + https://2captcha.com/ru/blog/reportgood-reportbad + + We recommend reporting both incorrect and correct answers. Args: locator (str): The XPath locator of the success message. + id (str): The captcha id for reporting. """ - message = get_element(locator).text - print(message) + try: + # Check for success message + message = get_present_element(locator).text + print(message) + is_success = True + + except TimeoutException: + # If the element is not found within the timeout + print("Timed out waiting for success message element") + is_success = False + except Exception as e: + # If another error occurs + print(f"Error retrieving final message: {e}") + is_success = False + + # Send the report anyway + solver.report(id, is_success) + print(f"Report sent for id: {id}, success: {is_success}") # MAIN LOGIC with webdriver.Chrome() as browser: - # Go to the specified URL browser.get(url) print('Started') - # Getting sitekey from the sitekey element + # Getting a site key sitekey = get_sitekey(sitekey_locator) - # Solving the captcha and receiving a token - token = solver_captcha(apikey, sitekey, url) - - if token: - # Sending solved captcha token - send_token(token) - - # Receiving and displaying a success message - final_message(success_message_locator) - - browser.implicitly_wait(5) - print("Finished") + if sitekey: + # Sent captcha to the solution in 2captcha API + result = solver_captcha(sitekey, url) + + if result: + # From the response from the service we get the captcha id and token + id, token = result['captchaId'], result['code'] + # Applying the token using the callback function + send_token(token) + + # We check if there is a message about the successful solution of the captcha and send a report on the result + # using the captcha id + final_message_and_report(success_message_locator, id) + print("Finished") + else: + print("Failed to solve captcha") else: - print("Failed to solve captcha") + print("Sitekey not found") diff --git a/examples/reCAPTCHA/recaptcha_v2_callback_variant2.py b/examples/reCAPTCHA/recaptcha_v2_callback_variant2.py index 0b6ff00..b370962 100644 --- a/examples/reCAPTCHA/recaptcha_v2_callback_variant2.py +++ b/examples/reCAPTCHA/recaptcha_v2_callback_variant2.py @@ -2,6 +2,7 @@ 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.common.exceptions import TimeoutException import os import time from twocaptcha import TwoCaptcha @@ -15,6 +16,8 @@ url = "https://2captcha.com/demo/recaptcha-v2-callback" apikey = os.getenv('APIKEY_2CAPTCHA') +solver = TwoCaptcha(apikey) + # JavaScript script to find reCAPTCHA clients and extract sitekey and callback function script = """ function findRecaptchaClients() { @@ -66,9 +69,9 @@ # GETTERS -def get_element(locator): - """Waits for an element to be clickable and returns it""" - return WebDriverWait(browser, 30).until(EC.element_to_be_clickable((By.XPATH, locator))) +def get_present_element(locator): + """Waits for an element to be present and returns it""" + return WebDriverWait(browser, 30).until(EC.presence_of_element_located((By.XPATH, locator))) # ACTIONS @@ -88,6 +91,7 @@ def get_captcha_params(script): result = browser.execute_script(script) if not result or not result[0]: raise IndexError("Callback name is empty or null") + # Extract the function name and sitekey callback_function_name = result[0]['function'] sitekey = result[0]['sitekey'] print("Got the callback function name and site key") @@ -96,22 +100,20 @@ def get_captcha_params(script): retries += 1 time.sleep(1) # Wait a bit before retrying -def solver_captcha(apikey, sitekey, url): +def solver_captcha(sitekey, url): """ Solves the reCaptcha using the 2Captcha service. Args: - apikey (str): The 2Captcha API key. sitekey (str): The sitekey for the captcha. url (str): The URL where the captcha is located. Returns: - str: The solved captcha code. + dict: The captcha id and the solved captcha code. """ - solver = TwoCaptcha(apikey) try: result = solver.recaptcha(sitekey=sitekey, url=url) - print(f"Captcha solved") - return result['code'] + print(f"Captcha solved. Token: {result['code']}.") + return result except Exception as e: print(f"An error occurred: {e}") return None @@ -128,38 +130,65 @@ def send_token_callback(callback_function, token): browser.execute_script(script) print("The token is sent to the callback function") -def final_message(locator): +def final_message_and_report(locator, id): """ - Retrieves and prints the final success message. + Retrieves and prints the final success message and sends a report to 2Captcha. + + Submitting answer reports is not necessary to solve the captcha. But it can help you reduce the cost of the solution + and improve accuracy. We have described why it is important to submit reports in our blog: + https://2captcha.com/ru/blog/reportgood-reportbad + + We recommend reporting both incorrect and correct answers. Args: locator (str): The XPath locator of the success message. + id (str): The captcha id for reporting. """ - message = get_element(locator).text - print(message) + try: + # Check for success message + message = get_present_element(locator).text + print(message) + is_success = True + + except TimeoutException: + # If the element is not found within the timeout + print("Timed out waiting for success message element") + is_success = False + except Exception as e: + # If another error occurs + print(f"Error retrieving final message: {e}") + is_success = False + + # Send the report anyway + solver.report(id, is_success) + print(f"Report sent for id: {id}, success: {is_success}") with webdriver.Chrome() as browser: browser.get(url) print("Started") - # Extracting callback function name and sitekey using the provided script + # Getting a site key and callback function callback_function, sitekey = get_captcha_params(script) - # Solving the captcha and receiving the token - token = solver_captcha(apikey, sitekey, url) - - if token: - # Sending the solved captcha token to the callback function - send_token_callback(callback_function, token) - - # Retrieving and printing the final success message - final_message(success_message_locator) - - browser.implicitly_wait(5) - print("Finished") + if sitekey: + # Sent captcha to the solution in 2captcha API + result = solver_captcha(sitekey, url) + + if result: + # From the response from the service we get the captcha id and token + id, token = result['captchaId'], result['code'] + # Applying the token using the callback function + send_token_callback(callback_function, token) + + # We check if there is a message about the successful solution of the captcha and send a report on the result + # using the captcha id + final_message_and_report(success_message_locator, id) + print("Finished") + else: + print("Failed to solve captcha") else: - print("Failed to solve captcha") + print("Sitekey not found") diff --git a/examples/reCAPTCHA/recaptcha_v2_proxy.py b/examples/reCAPTCHA/recaptcha_v2_proxy.py index 0069f74..24ecf05 100644 --- a/examples/reCAPTCHA/recaptcha_v2_proxy.py +++ b/examples/reCAPTCHA/recaptcha_v2_proxy.py @@ -3,6 +3,7 @@ from selenium.webdriver.support.wait import WebDriverWait from selenium.webdriver.chrome.options import Options from selenium.webdriver.support import expected_conditions as EC +from selenium.common.exceptions import TimeoutException from webdriver_manager.chrome import ChromeDriverManager from selenium.webdriver.chrome.service import Service import os @@ -16,6 +17,7 @@ proxy = {'type': 'HTTPS', 'uri': 'username:password@ip:port'} +solver = TwoCaptcha(apikey) # LOCATORS @@ -26,10 +28,14 @@ # GETTERS -def get_element(locator): +def get_clickable_element(locator): """Waits for an element to be clickable and returns it""" return WebDriverWait(browser, 30).until(EC.element_to_be_clickable((By.XPATH, locator))) +def get_present_element(locator): + """Waits for an element to be present and returns it""" + return WebDriverWait(browser, 30).until(EC.presence_of_element_located((By.XPATH, locator))) + # ACTIONS @@ -39,13 +45,23 @@ def parse_proxy_uri(proxy): Args: proxy (dict): Dictionary containing the proxy type and URI. + Example: + proxy = { + 'type': 'http', + 'uri': 'username:password@192.168.1.1:8080' + } Returns: tuple: A tuple containing scheme, login, password, IP, and port. """ + # Extract proxy type and convert to lowercase scheme = proxy['type'].lower + # Split URI into authentication info and address (IP:port) auth, address = proxy['uri'].split('@') + # Extract login and password from auth login, password = auth.split(':') + # Extract IP and port from address ip, port = address.split(':') + # Return extracted proxy details return scheme, login, password, ip, port def setup_proxy(proxy): @@ -58,10 +74,15 @@ def setup_proxy(proxy): Returns: Options: Configured Chrome options with proxy settings. """ + # Initialize Chrome options to modify default Chrome behavior chrome_options = webdriver.ChromeOptions() + # Extract proxy details (scheme, username, password, IP, port) scheme, username, password, ip, port = parse_proxy_uri(proxy) + # Create a proxy extension with the extracted credentials proxies_extension = proxies(scheme, username, password, ip, port) + # Add proxy extension to Chrome options chrome_options.add_extension(proxies_extension) + # Return the configured Chrome options return chrome_options def get_sitekey(locator): @@ -73,28 +94,26 @@ def get_sitekey(locator): Returns: str: The sitekey value. """ - sitekey_element = get_element(locator) + sitekey_element = get_present_element(locator) sitekey = sitekey_element.get_attribute('data-sitekey') print(f"Sitekey received: {sitekey}") return sitekey -def solver_captcha(apikey, sitekey, url, proxy): +def solver_captcha(sitekey, url, proxy): """ Solves the reCaptcha using the 2Captcha service. Args: - apikey (str): The 2Captcha API key. sitekey (str): The sitekey for the captcha. url (str): The URL where the captcha is located. proxy (dict): Dictionary containing the proxy settings. Returns: - str: The solved captcha code, or None if an error occurred. + dict: The captcha id and the solved captcha code. """ - solver = TwoCaptcha(apikey) try: result = solver.recaptcha(sitekey=sitekey, url=url, proxy=proxy) - print(f"Captcha solved") - return result['code'] + print(f"Captcha solved. Token: {result['code']}.") + return result except Exception as e: print(f"An error occurred: {e}") return None @@ -119,18 +138,41 @@ def click_check_button(locator): Args: locator (str): The XPath locator of the check button. """ - get_element(locator).click() + get_clickable_element(locator).click() print("Pressed the Check button") -def final_message(locator): +def final_message_and_report(locator, id): """ - Retrieves and prints the final success message. + Retrieves and prints the final success message and sends a report to 2Captcha. + + Submitting answer reports is not necessary to solve the captcha. But it can help you reduce the cost of the solution + and improve accuracy. We have described why it is important to submit reports in our blog: + https://2captcha.com/ru/blog/reportgood-reportbad + + We recommend reporting both incorrect and correct answers. Args: locator (str): The XPath locator of the success message. + id (str): The captcha id for reporting. """ - message = get_element(locator).text - print(message) + try: + # Check for success message + message = get_present_element(locator).text + print(message) + is_success = True + + except TimeoutException: + # If the element is not found within the timeout + print("Timed out waiting for success message element") + is_success = False + except Exception as e: + # If another error occurs + print(f"Error retrieving final message: {e}") + is_success = False + + # Send the report anyway + solver.report(id, is_success) + print(f"Report sent for id: {id}, success: {is_success}") # MAIN LOGIC @@ -139,27 +181,30 @@ def final_message(locator): chrome_options = setup_proxy(proxy) with webdriver.Chrome(service=Service(ChromeDriverManager().install()), options=chrome_options) as browser: - # Go to the specified URL browser.get(url) print('Started') - # Getting sitekey from the sitekey element + # Getting a site key sitekey = get_sitekey(sitekey_locator) - # Solving the captcha and receiving a token - token = solver_captcha(apikey, sitekey, url, proxy) - - if token: - # Sending solved captcha token - send_token(token) - - # Pressing the Check button - click_check_button(submit_button_captcha_locator) - - # Receiving and displaying a success message - final_message(success_message_locator) - - browser.implicitly_wait(5) - print("Finished") + if sitekey: + # Sent captcha to the solution in 2captcha API + result = solver_captcha(sitekey, url, proxy) + + if result: + # From the response from the service we get the captcha id and token + id, token = result['captchaId'], result['code'] + # Applying the token on the page + send_token(token) + # Checking whether the token has been accepted + click_check_button(submit_button_captcha_locator) + + # We check if there is a message about the successful solution of the captcha and send a report on the result + # using the captcha id + final_message_and_report(success_message_locator, id) + print("Finished") + else: + print("Failed to solve captcha") else: - print("Failed to solve captcha") + print("Sitekey not found") + diff --git a/examples/reCAPTCHA/recaptcha_v3.py b/examples/reCAPTCHA/recaptcha_v3.py index eeb5bbd..c00bf9f 100644 --- a/examples/reCAPTCHA/recaptcha_v3.py +++ b/examples/reCAPTCHA/recaptcha_v3.py @@ -2,6 +2,7 @@ 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.common.exceptions import TimeoutException import os import time from twocaptcha import TwoCaptcha @@ -12,6 +13,8 @@ url = "https://2captcha.com/demo/recaptcha-v3" apikey = os.getenv('APIKEY_2CAPTCHA') +solver = TwoCaptcha(apikey) + script = """ function findRecaptchaData() { const results = []; @@ -47,10 +50,14 @@ # GETTERS -def get_element(locator): +def get_clickable_element(locator): """Waits for an element to be clickable and returns it""" return WebDriverWait(browser, 30).until(EC.element_to_be_clickable((By.XPATH, locator))) +def get_present_element(locator): + """Waits for an element to be present and returns it""" + return WebDriverWait(browser, 30).until(EC.presence_of_element_located((By.XPATH, locator))) + # ACTIONS @@ -70,6 +77,7 @@ def get_captcha_params(script): result = browser.execute_script(script) if not result or not result[0]: raise IndexError("No reCaptcha parameters found") + # Extract the action's value and sitekey sitekey = result[0]['sitekey'] action = result[0]['action'] print('Parameters sitekey and action received') @@ -81,22 +89,21 @@ def get_captcha_params(script): print('No reCaptcha parameters found after retries') return None, None -def solver_captcha(apikey, sitekey, url, action): +def solver_captcha(sitekey, url, action): """ Solves the reCaptcha using the 2Captcha service. Args: - apikey (str): The 2Captcha API key. sitekey (str): The sitekey for the captcha. url (str): The URL where the captcha is located. + action (str): The value of the action parameter that you found in the site code. Returns: - str: The solved captcha code. + dict: The captcha id and the solved captcha code. """ - solver = TwoCaptcha(apikey) try: result = solver.recaptcha(sitekey=sitekey, url=url, action=action, version='V3') - print(f"Captcha solved") - return result['code'] + print(f"Captcha solved. Token: {result['code']}.") + return result except Exception as e: print(f"An error occurred: {e}") return None @@ -119,18 +126,41 @@ def click_check_button(locator): Args: locator (str): The XPath locator of the check button. """ - get_element(locator).click() + get_clickable_element(locator).click() print("Pressed the Check button") -def final_message(locator): +def final_message_and_report(locator, id): """ - Retrieves and prints the final success message. + Retrieves and prints the final success message and sends a report to 2Captcha. + + Submitting answer reports is not necessary to solve the captcha. But it can help you reduce the cost of the solution + and improve accuracy. We have described why it is important to submit reports in our blog: + https://2captcha.com/ru/blog/reportgood-reportbad + + We recommend reporting both incorrect and correct answers. Args: locator (str): The XPath locator of the success message. + id (str): The captcha id for reporting. """ - message = get_element(locator).text - print(message) + try: + # Check for success message + message = get_present_element(locator).text + print(message) + is_success = True + + except TimeoutException: + # If the element is not found within the timeout + print("Timed out waiting for success message element") + is_success = False + except Exception as e: + # If another error occurs + print(f"Error retrieving final message: {e}") + is_success = False + + # Send the report anyway + solver.report(id, is_success) + print(f"Report sent for id: {id}, success: {is_success}") # MAIN LOGIC @@ -139,25 +169,28 @@ def final_message(locator): browser.get(url) print("Started") - # Get captcha parameters + # Getting a site key and action's value sitekey, action = get_captcha_params(script) - # Solve the captcha - token = solver_captcha(apikey, sitekey, url, action) - - if token: - # Send the token - send_token(token) - - # Click the check button - click_check_button(submit_button_captcha_locator) - - # Get the final success message - final_message(success_message_locator) - - browser.implicitly_wait(5) - print("Finished") + if sitekey: + # Sent captcha to the solution in 2captcha API + result = solver_captcha(sitekey, url, action) + + if result: + # From the response from the service we get the captcha id and token + id, token = result['captchaId'], result['code'] + # Applying the token on the page + send_token(token) + # Checking whether the token has been accepted + click_check_button(submit_button_captcha_locator) + # We check if there is a message about the successful solution of the captcha and send a report on the result + # using the captcha id + final_message_and_report(success_message_locator, id) + print("Finished") + else: + print("Failed to solve captcha") else: - print("Failed to solve captcha") + print("Sitekey not found") + diff --git a/examples/reCAPTCHA/recaptcha_v3_extended_js_script.py b/examples/reCAPTCHA/recaptcha_v3_extended_js_script.py index 7004abf..8fabfe4 100644 --- a/examples/reCAPTCHA/recaptcha_v3_extended_js_script.py +++ b/examples/reCAPTCHA/recaptcha_v3_extended_js_script.py @@ -2,6 +2,7 @@ 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.common.exceptions import TimeoutException import os import time from twocaptcha import TwoCaptcha @@ -12,6 +13,8 @@ url = "https://2captcha.com/demo/recaptcha-v3" apikey = os.getenv('APIKEY_2CAPTCHA') +solver = TwoCaptcha(apikey) + script = """ function findRecaptchaData() { const results = []; @@ -70,10 +73,14 @@ # GETTERS -def get_element(locator): +def get_clickable_element(locator): """Waits for an element to be clickable and returns it""" return WebDriverWait(browser, 30).until(EC.element_to_be_clickable((By.XPATH, locator))) +def get_present_element(locator): + """Waits for an element to be present and returns it""" + return WebDriverWait(browser, 30).until(EC.presence_of_element_located((By.XPATH, locator))) + # ACTIONS @@ -93,6 +100,7 @@ def get_captcha_params(script): result = browser.execute_script(script) if not result or not result[0]: raise IndexError("No reCaptcha parameters found") + # Extract the action's value and sitekey sitekey = result[0]['sitekey'] action = result[0]['action'] print('Parameters sitekey and action received') @@ -104,22 +112,21 @@ def get_captcha_params(script): print('No reCaptcha parameters found after retries') return None, None -def solver_captcha(apikey, sitekey, url, action): +def solver_captcha(sitekey, url, action): """ Solves the reCaptcha using the 2Captcha service. Args: - apikey (str): The 2Captcha API key. sitekey (str): The sitekey for the captcha. url (str): The URL where the captcha is located. + action (str): The value of the action parameter that you found in the site code. Returns: - str: The solved captcha code. + dict: The captcha id and the solved captcha code. """ - solver = TwoCaptcha(apikey) try: result = solver.recaptcha(sitekey=sitekey, url=url, action=action, version='V3') - print(f"Captcha solved") - return result['code'] + print(f"Captcha solved. Token: {result['code']}.") + return result except Exception as e: print(f"An error occurred: {e}") return None @@ -142,18 +149,41 @@ def click_check_button(locator): Args: locator (str): The XPath locator of the check button. """ - get_element(locator).click() + get_clickable_element(locator).click() print("Pressed the Check button") -def final_message(locator): +def final_message_and_report(locator, id): """ - Retrieves and prints the final success message. + Retrieves and prints the final success message and sends a report to 2Captcha. + + Submitting answer reports is not necessary to solve the captcha. But it can help you reduce the cost of the solution + and improve accuracy. We have described why it is important to submit reports in our blog: + https://2captcha.com/ru/blog/reportgood-reportbad + + We recommend reporting both incorrect and correct answers. Args: locator (str): The XPath locator of the success message. + id (str): The captcha id for reporting. """ - message = get_element(locator).text - print(message) + try: + # Check for success message + message = get_present_element(locator).text + print(message) + is_success = True + + except TimeoutException: + # If the element is not found within the timeout + print("Timed out waiting for success message element") + is_success = False + except Exception as e: + # If another error occurs + print(f"Error retrieving final message: {e}") + is_success = False + + # Send the report anyway + solver.report(id, is_success) + print(f"Report sent for id: {id}, success: {is_success}") # MAIN LOGIC @@ -162,25 +192,30 @@ def final_message(locator): browser.get(url) print("Started") - # Get captcha parameters + # Getting a site key and action's value sitekey, action = get_captcha_params(script) - # Solve the captcha - token = solver_captcha(apikey, sitekey, url, action) - - if token: - # Send the token - send_token(token) - - # Click the check button - click_check_button(submit_button_captcha_locator) + if sitekey: + # Sent captcha to the solution in 2captcha API + result = solver_captcha(sitekey, url, action) + + if result: + # From the response from the service we get the captcha id and token + id, token = result['captchaId'], result['code'] + # Applying the token on the page + send_token(token) + # Checking whether the token has been accepted + click_check_button(submit_button_captcha_locator) + + # We check if there is a message about the successful solution of the captcha and send a report on the result + # using the captcha id + final_message_and_report(success_message_locator, id) + print("Finished") + else: + print("Failed to solve captcha") + else: + print("Sitekey not found") - # Get the final success message - final_message(success_message_locator) - browser.implicitly_wait(5) - print("Finished") - else: - print("Failed to solve captcha") diff --git a/examples/reCAPTCHA/recaptcha_v3_proxy.py b/examples/reCAPTCHA/recaptcha_v3_proxy.py index 15a707d..35209c0 100644 --- a/examples/reCAPTCHA/recaptcha_v3_proxy.py +++ b/examples/reCAPTCHA/recaptcha_v3_proxy.py @@ -3,6 +3,7 @@ from selenium.webdriver.support.wait import WebDriverWait from selenium.webdriver.chrome.options import Options from selenium.webdriver.support import expected_conditions as EC +from selenium.common.exceptions import TimeoutException from webdriver_manager.chrome import ChromeDriverManager from selenium.webdriver.chrome.service import Service import os @@ -18,6 +19,8 @@ proxy = {'type': 'HTTPS', 'uri': 'username:password@ip:port'} +solver = TwoCaptcha(apikey) + script = """ function findRecaptchaData() { const results = []; @@ -53,10 +56,14 @@ # GETTERS -def get_element(locator): +def get_clickable_element(locator): """Waits for an element to be clickable and returns it""" return WebDriverWait(browser, 30).until(EC.element_to_be_clickable((By.XPATH, locator))) +def get_present_element(locator): + """Waits for an element to be present and returns it""" + return WebDriverWait(browser, 30).until(EC.presence_of_element_located((By.XPATH, locator))) + # ACTIONS @@ -66,13 +73,23 @@ def parse_proxy_uri(proxy): Args: proxy (dict): Dictionary containing the proxy type and URI. + Example: + proxy = { + 'type': 'http', + 'uri': 'username:password@192.168.1.1:8080' + } Returns: tuple: A tuple containing scheme, login, password, IP, and port. """ + # Extract proxy type and convert to lowercase scheme = proxy['type'].lower + # Split URI into authentication info and address (IP:port) auth, address = proxy['uri'].split('@') + # Extract login and password from auth login, password = auth.split(':') + # Extract IP and port from address ip, port = address.split(':') + # Return extracted proxy details return scheme, login, password, ip, port def setup_proxy(proxy): @@ -85,10 +102,15 @@ def setup_proxy(proxy): Returns: Options: Configured Chrome options with proxy settings. """ + # Initialize Chrome options to modify default Chrome behavior chrome_options = webdriver.ChromeOptions() + # Extract proxy details (scheme, username, password, IP, port) scheme, username, password, ip, port = parse_proxy_uri(proxy) + # Create a proxy extension with the extracted credentials proxies_extension = proxies(scheme, username, password, ip, port) + # Add proxy extension to Chrome options chrome_options.add_extension(proxies_extension) + # Return the configured Chrome options return chrome_options def get_captcha_params(script): @@ -107,6 +129,7 @@ def get_captcha_params(script): result = browser.execute_script(script) if not result or not result[0]: raise IndexError("No reCaptcha parameters found") + # Extract the action's value and sitekey sitekey = result[0]['sitekey'] action = result[0]['action'] print('Parameters sitekey and action received') @@ -118,22 +141,22 @@ def get_captcha_params(script): print('No reCaptcha parameters found after retries') return None, None -def solver_captcha(apikey, sitekey, url, action, proxy): +def solver_captcha(sitekey, url, action, proxy): """ Solves the reCaptcha using the 2Captcha service. Args: - apikey (str): The 2Captcha API key. sitekey (str): The sitekey for the captcha. url (str): The URL where the captcha is located. + action (str): The value of the action parameter that you found in the site code. + proxy (dict): Dictionary containing the proxy settings. Returns: - str: The solved captcha code. + dict: The captcha id and the solved captcha code. """ - solver = TwoCaptcha(apikey) try: result = solver.recaptcha(sitekey=sitekey, url=url, action=action, version='V3', proxy=proxy) - print(f"Captcha solved") - return result['code'] + print(f"Captcha solved. Token: {result['code']}.") + return result except Exception as e: print(f"An error occurred: {e}") return None @@ -156,47 +179,73 @@ def click_check_button(locator): Args: locator (str): The XPath locator of the check button. """ - get_element(locator).click() + get_clickable_element(locator).click() print("Pressed the Check button") -def final_message(locator): +def final_message_and_report(locator, id): """ - Retrieves and prints the final success message. + Retrieves and prints the final success message and sends a report to 2Captcha. + + Submitting answer reports is not necessary to solve the captcha. But it can help you reduce the cost of the solution + and improve accuracy. We have described why it is important to submit reports in our blog: + https://2captcha.com/ru/blog/reportgood-reportbad + + We recommend reporting both incorrect and correct answers. Args: locator (str): The XPath locator of the success message. + id (str): The captcha id for reporting. """ - message = get_element(locator).text - print(message) + try: + # Check for success message + message = get_present_element(locator).text + print(message) + is_success = True + + except TimeoutException: + # If the element is not found within the timeout + print("Timed out waiting for success message element") + is_success = False + except Exception as e: + # If another error occurs + print(f"Error retrieving final message: {e}") + is_success = False + + # Send the report anyway + solver.report(id, is_success) + print(f"Report sent for id: {id}, success: {is_success}") # MAIN LOGIC +# Configure Chrome options with proxy settings chrome_options = setup_proxy(proxy) with webdriver.Chrome(service=Service(ChromeDriverManager().install()), options=chrome_options) as browser: browser.get(url) print("Started") - # Get captcha parameters + # Getting a site key and action's value sitekey, action = get_captcha_params(script) - # Solve the captcha - token = solver_captcha(apikey, sitekey, url, action, proxy) - - if token: - # Send the token - send_token(token) - - # Click the check button - click_check_button(submit_button_captcha_locator) - - # Get the final success message - final_message(success_message_locator) - - browser.implicitly_wait(5) - print("Finished") + if sitekey: + # Sent captcha to the solution in 2captcha API + result = solver_captcha(sitekey, url, action, proxy) + + if result: + # From the response from the service we get the captcha id and token + id, token = result['captchaId'], result['code'] + # Applying the token on the page + send_token(token) + # Checking whether the token has been accepted + click_check_button(submit_button_captcha_locator) + # We check if there is a message about the successful solution of the captcha and send a report on the result + # using the captcha id + final_message_and_report(success_message_locator, id) + print("Finished") + else: + print("Failed to solve captcha") else: - print("Failed to solve captcha") + print("Sitekey not found") diff --git a/examples/text_captcha/text_captcha.py b/examples/text_captcha/text_captcha.py index ca9b0c9..73bcb36 100644 --- a/examples/text_captcha/text_captcha.py +++ b/examples/text_captcha/text_captcha.py @@ -2,6 +2,7 @@ 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.common.exceptions import TimeoutException import os from twocaptcha import TwoCaptcha @@ -11,6 +12,8 @@ url = "https://2captcha.com/demo/text" apikey = os.getenv('APIKEY_2CAPTCHA') +solver = TwoCaptcha(apikey) + # LOCATORS @@ -21,10 +24,14 @@ # GETTERS -def get_element(locator): +def get_clickable_element(locator): """Waits for an element to be clickable and returns it""" return WebDriverWait(browser, 30).until(EC.element_to_be_clickable((By.XPATH, locator))) +def get_present_element(locator): + """Waits for an element to be present and returns it""" + return WebDriverWait(browser, 30).until(EC.presence_of_element_located((By.XPATH, locator))) + # ACTIONS @@ -33,29 +40,28 @@ def get_captcha_question(locator): Extracts the captcha question text from the specified element. Args: - locator (str): XPath locator of the captcha question element + locator (str): XPath locator of the captcha question element. Returns: - str: Text of the captcha question + str: Text of the captcha question. """ - question_element = get_element(locator) + question_element = get_present_element(locator) text_question = question_element.text return text_question -def solver_captcha(question, apikey): +def solver_captcha(question): """ - Solves a captcha using the 2Captcha service and returns the solution code + Solves a captcha using the 2Captcha service and returns the solution code. Args: - image (str): Path to the captcha image - apikey (str): API key to access the 2Captcha service + question (str): Captcha text. + apikey (str): API key to access the 2Captcha service. Returns: - str: Captcha solution code, if successful, otherwise None + dict: The captcha id and the solved captcha code. """ - solver = TwoCaptcha(apikey) try: result = solver.text(question) - print(f"Captcha solved. Code: {result['code']}") - return result['code'] + print(f"Captcha solved. Answer: {result['code']}.") + return result except Exception as e: print(f"An error occurred: {e}") return None @@ -65,60 +71,81 @@ def send_answer(locator, answer): Inputs the captcha answer into the specified input field. Args: - locator (str): XPath locator of the input field - answer (str): Captcha answer + locator (str): XPath locator of the input field. + answer (str): Captcha answer. """ - input_element = get_element(locator) + input_element = get_clickable_element(locator) input_element.send_keys(answer) print("Entering the answer to captcha") def click_check_button(locator): """ - Clicks the check button on a web page + Clicks the check button on a web page. Args: - locator (str): XPATH locator of the captcha verification button + locator (str): XPATH locator of the captcha verification button. """ - button = get_element(locator) + button = get_clickable_element(locator) button.click() print("Pressed the Check button") -def final_message(locator): +def final_message_and_report(locator, id): """ - Retrieves and prints the final success message. + Retrieves and prints the final success message and sends a report to 2Captcha. + + Submitting answer reports is not necessary to solve the captcha. But it can help you reduce the cost of the solution + and improve accuracy. We have described why it is important to submit reports in our blog: + https://2captcha.com/ru/blog/reportgood-reportbad + + We recommend reporting both incorrect and correct answers. Args: locator (str): The XPath locator of the success message. + id (str): The captcha id for reporting. """ - message = get_element(locator).text - print(message) + try: + # Check for success message + message = get_present_element(locator).text + print(message) + is_success = True + + except TimeoutException: + # If the element is not found within the timeout + print("Timed out waiting for success message element") + is_success = False + except Exception as e: + # If another error occurs + print(f"Error retrieving final message: {e}") + is_success = False + + # Send the report anyway + solver.report(id, is_success) + print(f"Report sent for id: {id}, success: {is_success}") # MAIN LOGIC # Automatically closes the browser after block execution completes with webdriver.Chrome() as browser: - # Go to page with captcha browser.get(url) print("Started") - # Get the text of the captcha question + # Geeting a captcha question captcha_question = get_captcha_question(captcha_question_locator) + # Sent captcha to the solution in 2captcha API + result = solver_captcha(captcha_question) - # Solve the captcha using 2Captcha - answer = solver_captcha(captcha_question, apikey) - - if answer: - # Enter the captcha answer + if result: + # From the response from the service we get the captcha id and an answer + id, answer = result['captchaId'], result['code'] + # Sending an answer send_answer(captcha_input_locator, answer) - - # Click the check button + # Check if the answer is accepted click_check_button(submit_button_captcha_locator) + # We check if there is a message about the successful solution of the captcha and send a report on the result + # using the captcha id + final_message_and_report(success_message_locator, id) - # Retrieve and display the success message - final_message(success_message_locator) - - browser.implicitly_wait(5) print("Finished") else: print("Failed to solve captcha")