### Clone Repository and Install Requirements Source: https://github.com/2captcha/selenium-recaptcha-solver-using-grid/blob/main/README.md Clone the project repository and install the necessary Python libraries using pip. ```bash git clone git@github.com:2captcha/recaptcha-solver-using-grid.git cd recaptcha-solver-using-grid ``` ```bash pip install -r requirements.txt ``` -------------------------------- ### Install Dependencies and Set API Key Source: https://context7.com/2captcha/selenium-recaptcha-solver-using-grid/llms.txt Install required Python packages and set your 2Captcha API key as an environment variable before running the solver. ```bash pip install -r requirements.txt # requirements.txt contains: # 2captcha-python==1.5.0 # selenium==4.25.0 # seleniumbase export APIKEY_2CAPTCHA=your_api_key_here python main.py ``` -------------------------------- ### Run the Captcha Solver Script Source: https://github.com/2captcha/selenium-recaptcha-solver-using-grid/blob/main/README.md Execute the main Python script to start the reCAPTCHA solving process. ```bash python main.py ``` -------------------------------- ### Reset JS Image Update Observation Window Source: https://context7.com/2captcha/selenium-recaptcha-solver-using-grid/llms.txt Calls the `resetImageUpdateFlag()` JavaScript function to clear network request counters and start a fresh observation window before new clicks are made. ```python page_actions.reset_image_update_flag() ``` -------------------------------- ### CaptchaHelper.__init__ Source: https://context7.com/2captcha/selenium-recaptcha-solver-using-grid/llms.txt Initializes the CaptchaHelper with a browser driver and a TwoCaptcha solver instance. ```APIDOC ## CaptchaHelper.__init__ ### Description Initializes a `CaptchaHelper` bound to the browser driver and a configured `TwoCaptcha` solver instance. Also internally instantiates a `PageActions` object for element visibility checks. ### Method ```python captcha_helper = CaptchaHelper(browser, solver) ``` ### Parameters * **browser**: The Selenium WebDriver instance. * **solver**: The configured TwoCaptcha solver instance. ### Request Example ```python import os from twocaptcha import TwoCaptcha from seleniumbase import Driver from utils.helpers import CaptchaHelper apikey = os.getenv('APIKEY_2CAPTCHA') solver = TwoCaptcha(apikey, pollingInterval=1) with Driver(browser="chrome", locale_code="en") as browser: captcha_helper = CaptchaHelper(browser, solver) ``` ``` -------------------------------- ### Initialize Captcha Solver Helper Source: https://context7.com/2captcha/selenium-recaptcha-solver-using-grid/llms.txt Initializes a CaptchaHelper instance, which requires a Selenium browser driver and a configured TwoCaptcha solver. It also sets up an internal PageActions object for visibility checks. ```python import os from twocaptcha import TwoCaptcha from seleniumbase import Driver from utils.helpers import CaptchaHelper apikey = os.getenv('APIKEY_2CAPTCHA') solver = TwoCaptcha(apikey, pollingInterval=1) with Driver(browser="chrome", locale_code="en") as browser: captcha_helper = CaptchaHelper(browser, solver) ``` -------------------------------- ### CaptchaHelper.load_js_script Source: https://context7.com/2captcha/selenium-recaptcha-solver-using-grid/llms.txt Loads a JavaScript file from disk and returns its content as a string. ```APIDOC ## CaptchaHelper.load_js_script ### Description Reads a `.js` file and returns its contents as a string, ready to be injected into the browser via `execute_js`. ### Method ```python some_js_content = captcha_helper.load_js_script('path/to/your/script.js') ``` ### Parameters * **script_path** (str) - The path to the JavaScript file. ### Response * **str**: The content of the JavaScript file. ### Request Example ```python script_get_data = captcha_helper.load_js_script('js_scripts/get_captcha_data.js') script_tracking = captcha_helper.load_js_script('js_scripts/track_image_updates.js') # Returns the full JS source as a string print(type(script_get_data)) # ``` ``` -------------------------------- ### Configure 2Captcha API Key Source: https://github.com/2captcha/selenium-recaptcha-solver-using-grid/blob/main/README.md Set the API key for the 2Captcha service either as an environment variable or directly in the main script. ```bash export APIKEY_2CAPTCHA=your_api_key ``` -------------------------------- ### PageActions.__init__ Source: https://context7.com/2captcha/selenium-recaptcha-solver-using-grid/llms.txt Initializes the PageActions class with a SeleniumBase WebDriver instance. This object is used for all subsequent browser interactions. ```APIDOC ## PageActions.__init__ — Initialize browser action handler Instantiates the `PageActions` class with a SeleniumBase/Selenium WebDriver instance. All subsequent browser interaction methods are called on this object. ```python from seleniumbase import Driver from utils.actions import PageActions with Driver(browser="chrome", locale_code="en") as browser: browser.get("https://2captcha.com/demo/recaptcha-v2") page_actions = PageActions(browser) # page_actions is now ready for all browser interaction methods ``` ``` -------------------------------- ### Initialize PageActions with WebDriver Source: https://context7.com/2captcha/selenium-recaptcha-solver-using-grid/llms.txt Instantiate the PageActions class with a SeleniumBase Driver instance. This object will be used for all subsequent browser interactions. ```python from seleniumbase import Driver from utils.actions import PageActions with Driver(browser="chrome", locale_code="en") as browser: browser.get("https://2captcha.com/demo/recaptcha-v2") page_actions = PageActions(browser) # page_actions is now ready for all browser interaction methods ``` -------------------------------- ### Load JavaScript File Content Source: https://context7.com/2captcha/selenium-recaptcha-solver-using-grid/llms.txt Reads a JavaScript file from disk and returns its content as a string. This string can then be injected into the browser using `execute_js`. ```python script_get_data = captcha_helper.load_js_script('js_scripts/get_captcha_data.js') script_tracking = captcha_helper.load_js_script('js_scripts/track_image_updates.js') # Returns the full JS source as a string print(type(script_get_data)) # ``` -------------------------------- ### Click reCAPTCHA Checkbox Source: https://context7.com/2captcha/selenium-recaptcha-solver-using-grid/llms.txt Waits until the checkbox element is clickable and then clicks it to trigger the image challenge popup. Ensure to switch to the correct iframe first. ```python c_checkbox_captcha = "//span[@role='checkbox']" page_actions.switch_to_iframe("//iframe[@title='reCAPTCHA']") page_actions.click_checkbox(c_checkbox_captcha) # Output: "Checked the checkbox" page_actions.switch_to_default_content() ``` -------------------------------- ### PageActions.switch_to_iframe Source: https://context7.com/2captcha/selenium-recaptcha-solver-using-grid/llms.txt Switches the WebDriver context into a specified iframe. It waits for the iframe to be present and then changes the focus to enable interaction with its elements. ```APIDOC ## PageActions.switch_to_iframe — Switch WebDriver context into a captcha iframe Waits for the specified iframe to be present in the DOM and switches the WebDriver focus into it, enabling interaction with elements inside the iframe. ```python # XPath locators for the two reCAPTCHA iframes c_iframe_captcha = "//iframe[@title='reCAPTCHA']" # checkbox iframe c_popup_captcha = "//iframe[contains(@title, 'two minutes')]" # image challenge iframe # Switch into the checkbox widget iframe page_actions.switch_to_iframe(c_iframe_captcha) # Output: "Switched to captcha widget" # After clicking the checkbox, switch back and then into the challenge iframe page_actions.switch_to_default_content() page_actions.switch_to_iframe(c_popup_captcha) # Output: "Returned focus to the main page content" # "Switched to captcha widget" ``` ``` -------------------------------- ### Click Verify, Reload, or Submit Button Source: https://context7.com/2captcha/selenium-recaptcha-solver-using-grid/llms.txt Waits briefly, then clicks the target button. Useful for the captcha verify button, reload button, or the page submit button. ```python c_verify_button = "//button[@id='recaptcha-verify-button']" c_reload_button = "//button[@id='recaptcha-reload-button']" p_submit_button_captcha = "//button[@type='submit']" # After selecting image tiles, press verify page_actions.click_check_button(c_verify_button) # Output: "Pressed the Check button" # If too many errors occur, reload the captcha page_actions.click_check_button(c_reload_button) # After the captcha is fully solved, submit the page form page_actions.switch_to_default_content() page_actions.click_check_button(p_submit_button_captcha) ``` -------------------------------- ### CaptchaHelper.execute_js Source: https://context7.com/2captcha/selenium-recaptcha-solver-using-grid/llms.txt Injects and executes JavaScript code within the browser context. ```APIDOC ## CaptchaHelper.execute_js ### Description Wraps `browser.execute_script()`. Used to inject the captcha data extractor and network monitor scripts into the captcha iframe context. ### Method ```python captcha_helper.execute_js(javascript_code) ``` ### Parameters * **javascript_code** (str) - The JavaScript code to execute. ### Request Example ```python # Inject both scripts once after switching into the challenge iframe script_get_data = captcha_helper.load_js_script('js_scripts/get_captcha_data.js') script_tracking = captcha_helper.load_js_script('js_scripts/track_image_updates.js') captcha_helper.execute_js(script_get_data) # Output: "Executing JS" captcha_helper.execute_js(script_tracking) # Output: "Executing JS" # After injection, call the exported function directly captcha_data = browser.execute_script("return getCaptchaData();") print(captcha_data) # { # 'rows': 3, 'columns': 3, 'type': 'GridTask', # 'comment': 'Select all images with traffic lights', # 'body': '' # } ``` ``` -------------------------------- ### PageActions.clicks Source: https://context7.com/2captcha/selenium-recaptcha-solver-using-grid/llms.txt Simulates clicks on specified elements, likely captcha tiles. ```APIDOC ## PageActions.clicks ### Description Simulates clicks on the specified elements, likely captcha tiles. This function is used in conjunction with `reset_image_update_flag()` and `check_for_image_updates()` to manage captcha solving. ### Method ``` page_actions.clicks([1, 4, 7]) ``` ### Parameters * **element_indices** (list of int) - A list of indices representing the elements to click. ``` -------------------------------- ### Reset Image Update Flag Source: https://context7.com/2captcha/selenium-recaptcha-solver-using-grid/llms.txt Call this before performing clicks to ensure subsequent checks only count requests from the new click batch. ```python page_actions.reset_image_update_flag() # Output: "Reset image update flag" ``` -------------------------------- ### Click Image Tile Cells by Index Source: https://context7.com/2captcha/selenium-recaptcha-solver-using-grid/llms.txt Iterates over a list of zero-based cell indices and clicks the corresponding `` elements in the reCAPTCHA image grid. Used to submit the answer returned by 2Captcha. ```python # answer_list is a list of 0-based cell indices (e.g., cells 0, 2, 5 in a 3x3 grid) answer_list = [0, 2, 5] page_actions.clicks(answer_list) # Clicks , , in the captcha table # Output: "Cells are marked" ``` -------------------------------- ### Switch WebDriver Context into Captcha Iframe Source: https://context7.com/2captcha/selenium-recaptcha-solver-using-grid/llms.txt Waits for the specified iframe to be present and switches WebDriver focus into it. Use default content to return focus to the main page. ```python # XPath locators for the two reCAPTCHA iframes c_iframe_captcha = "//iframe[@title='reCAPTCHA']" # checkbox iframe c_popup_captcha = "//iframe[contains(@title, 'two minutes')]" # image challenge iframe # Switch into the checkbox widget iframe page_actions.switch_to_iframe(c_iframe_captcha) # Output: "Switched to captcha widget" # After clicking the checkbox, switch back and then into the challenge iframe page_actions.switch_to_default_content() page_actions.switch_to_iframe(c_popup_captcha) # Output: "Returned focus to the main page content" # "Switched to captcha widget" ``` -------------------------------- ### Perform Clicks and Check for Image Updates Source: https://context7.com/2captcha/selenium-recaptcha-solver-using-grid/llms.txt Performs a series of clicks and then checks if the expected number of image updates (network requests) have occurred. Useful for determining if the captcha tiles have refreshed. ```python page_actions.clicks([1, 4, 7]) image_updated = page_actions.check_for_image_updates(expected_updates=3) ``` -------------------------------- ### Inject and Execute JavaScript in Browser Source: https://context7.com/2captcha/selenium-recaptcha-solver-using-grid/llms.txt Wraps `browser.execute_script()` to inject and run JavaScript code within the browser context, specifically used here for captcha-related scripts within the iframe. It also shows how to call injected JS functions directly. ```python # Inject both scripts once after switching into the challenge iframe script_get_data = captcha_helper.load_js_script('js_scripts/get_captcha_data.js') script_tracking = captcha_helper.load_js_script('js_scripts/track_image_updates.js') captcha_helper.execute_js(script_get_data) # Output: "Executing JS" captcha_helper.execute_js(script_tracking) # Output: "Executing JS" # After injection, call the exported function directly captcha_data = browser.execute_script("return getCaptchaData();") print(captcha_data) # { # 'rows': 3, 'columns': 3, 'type': 'GridTask', # 'comment': 'Select all images with traffic lights', # 'body': '' # } ``` -------------------------------- ### CaptchaHelper.pars_answer Source: https://context7.com/2captcha/selenium-recaptcha-solver-using-grid/llms.txt Parses the 2Captcha grid answer string (e.g., "OK:1/3/7") into a zero-based list of integer cell indices, converting from 1-based indices provided by 2Captcha to 0-based DOM `td[id]` values. ```APIDOC ## `CaptchaHelper.pars_answer` — Parse 2Captcha grid answer into click indices Converts the 2Captcha response string (e.g., `"OK:1/3/7"`) into a zero-based list of integer cell indices suitable for passing to `PageActions.clicks()`. 2Captcha uses 1-based indices; this method converts them to 0-based DOM `td[id]` values. ```python answer = "OK:1/3/7" number_list = captcha_helper.pars_answer(answer) # Output: "Parsed the response to a list of cell numbers" print(number_list) # [0, 2, 6] ← converted from 1-based to 0-based # Another example answer2 = "OK:2/5/8/11" number_list2 = captcha_helper.pars_answer(answer2) print(number_list2) # [1, 4, 7, 10] # Pass directly to clicks() page_actions.clicks(number_list) ``` ``` -------------------------------- ### CaptchaHelper.solver_captcha Source: https://context7.com/2captcha/selenium-recaptcha-solver-using-grid/llms.txt Submits a base64-encoded captcha image to the 2Captcha grid API. It accepts parameters for grid dimensions, instruction text, and language, returning a result dictionary with `captchaId` and `code`, or an unsolvable status, or None on error. ```APIDOC ## `CaptchaHelper.solver_captcha` — Submit captcha image to 2Captcha grid API Sends the base64-encoded captcha image to 2Captcha's `grid` method with parameters describing the grid dimensions, instruction text, and language. Returns a result dict with `captchaId` and `code`, or `{"unsolvable": True}` for `ERROR_CAPTCHA_UNSOLVABLE`, or `None` on other errors. ```python captcha_data = browser.execute_script("return getCaptchaData();") params = { "method": "base64", "img_type": "recaptcha", "recaptcha": 1, "cols": captcha_data['columns'], # 3 or 4 "rows": captcha_data['rows'], # 3 or 4 "textinstructions": captcha_data['comment'], # e.g. "Select all traffic lights" "lang": "en", "can_no_answer": 1, } # For 3x3 subsequent iterations, pass previousID to speed up solving if params['cols'] == 3 and saved_id: params["previousID"] = saved_id result = captcha_helper.solver_captcha(file=captcha_data['body'], **params) # Output: "Captcha solved" # Possible return values: # Success: {'captchaId': '61234567890', 'code': 'OK:1/3/7'} # No match: {'captchaId': '61234567891', 'code': 'OK:No_matching_images'} # Unsolvable: {'unsolvable': True} # Error: None if result is None: print("Fatal error — stop") elif result.get("unsolvable"): print("Unsolvable — retry same image") elif 'No_matching_images' in result['code']: print("No matching tiles — click verify and check for errors") else: print(f"Solved: {result['code']}") # e.g. "OK:1/3/7" saved_id = result['captchaId'] # Save for 3x3 previousID ``` ``` -------------------------------- ### Track reCAPTCHA Tile Replacements with JavaScript Source: https://context7.com/2captcha/selenium-recaptcha-solver-using-grid/llms.txt Use these JavaScript functions, injected via `track_image_updates.js`, to monitor calls to `recaptcha/api2/replaceimage`. `resetImageUpdateFlag()` clears counters, and `monitorRequests(n)` returns true when at least `n` replacement requests are observed. ```javascript // Inject track_image_updates.js once, then use these functions from Python: // Before clicking tiles, reset the counter resetImageUpdateFlag(); // window.__recaptchaReplaceImageCount = 0 // ... selenium clicks 3 tiles ... // Poll: returns true when 3 replaceimage requests have been seen const updated = monitorRequests(3); // true | false // Without argument: returns true if any replaceimage was seen const anyUpdate = monitorRequests(); // From Python via Selenium: // updated = browser.execute_script("return monitorRequests(arguments[0]);", 3) ``` -------------------------------- ### PageActions.check_for_image_updates Source: https://context7.com/2captcha/selenium-recaptcha-solver-using-grid/llms.txt Polls for captcha tile replacement requests to detect image updates. ```APIDOC ## PageActions.check_for_image_updates ### Description Polls up to `retries` times (default 10, every 0.5 s) checking whether the injected JS has detected the expected number of `replaceimage` network requests. Returns `True` if images were updated (meaning the loop must continue), `False` otherwise. ### Method ```python page_actions.check_for_image_updates(expected_updates=3, wait_time=0.5, retries=10) ``` ### Parameters * **expected_updates** (int, optional) - The expected number of replacement requests. Defaults to None. * **wait_time** (float, optional) - The time in seconds to wait between retries. Defaults to 0.5. * **retries** (int, optional) - The maximum number of retries. Defaults to 10. ### Response * **True**: If images were updated. * **False**: If no image updates were detected. ### Request Example ```python # 3x3: wait for exactly as many tile replacements as tiles clicked page_actions.reset_image_update_flag() page_actions.clicks([0, 3, 6]) image_update = page_actions.check_for_image_updates( expected_updates=3, # 3 tiles clicked → expect 3 replacement requests wait_time=0.5, retries=10 ) if image_update: print("New tiles loaded — continue solving loop") # Output: "Images updated (network requests detected)" else: print("No new tiles — proceed to verify") # Output: "No image updates detected" # 4x4: any update activity is sufficient (no expected_updates count needed) image_update = page_actions.check_for_image_updates() ``` ``` -------------------------------- ### getCaptchaData() (JavaScript) Source: https://context7.com/2captcha/selenium-recaptcha-solver-using-grid/llms.txt JavaScript function to extract captcha image data as a base64 string. ```APIDOC ## getCaptchaData() ### Description Injected into the captcha iframe. Detects whether the challenge is 3×3 or 4×4, composites the base image with any updated individual tiles onto a canvas, and returns a data object with the image encoded as a base64 JPEG string (without the `data:image/jpeg;base64,` prefix). ### Usage ```javascript // After injecting get_captcha_data.js, call from Python or browser console: const data = getCaptchaData(); ``` ### Response Structure ```json { "rows": 3, // or 4 "columns": 3, // or 4 "type": "GridTask", "comment": "Select all images with bicycles", // instruction text "body": "/9j/4AAQSkZJRgAB..." // base64 JPEG, no data URI prefix } ``` ### Request Example ```javascript // For 3x3: composites base 3x3 image + any rc-image-tile-11 overlay tiles // For 4x4: captures the single rc-image-tile-44 image directly const data = getCaptchaData(); console.log(`Grid: ${data.rows}x${data.columns}`); console.log(`Instruction: ${data.comment}`); console.log(`Image length: ${data.body.length} chars`); ``` ``` -------------------------------- ### PageActions.click_checkbox Source: https://context7.com/2captcha/selenium-recaptcha-solver-using-grid/llms.txt Clicks the reCAPTCHA "I'm not a robot" checkbox. This action triggers the image challenge popup if the challenge is presented. ```APIDOC ## PageActions.click_checkbox — Click the reCAPTCHA "I'm not a robot" checkbox Waits until the checkbox element is clickable, then clicks it to trigger the image challenge popup. ```python c_checkbox_captcha = "//span[@role='checkbox']" page_actions.switch_to_iframe("//iframe[@title='reCAPTCHA']") page_actions.click_checkbox(c_checkbox_captcha) # Output: "Checked the checkbox" page_actions.switch_to_default_content() ``` ``` -------------------------------- ### PageActions.get_clickable_element Source: https://context7.com/2captcha/selenium-recaptcha-solver-using-grid/llms.txt Waits for an element to be clickable within a specified timeout. ```APIDOC ## PageActions.get_clickable_element ### Description Low-level helper that uses `WebDriverWait` to wait up to `timeout` seconds for an element to be clickable. Returns the located WebElement. ### Method ```python page_actions.get_clickable_element("//button[@id='recaptcha-verify-button']", timeout=30) ``` ### Parameters * **locator** (str) - The locator string for the element. * **timeout** (int, optional) - The maximum time in seconds to wait for the element to be clickable. Defaults to None. ### Response * **WebElement**: The located and clickable WebElement. ### Request Example ```python # Wait up to 30 s for an element to be clickable verify_btn = page_actions.get_clickable_element( "//button[@id='recaptcha-verify-button']", timeout=30 ) verify_btn.click() ``` ``` -------------------------------- ### Wait for Element Presence Source: https://context7.com/2captcha/selenium-recaptcha-solver-using-grid/llms.txt Waits up to a specified timeout for an element to be present in the DOM. Returns the WebElement once it's present. Useful for checking for the existence of elements like error messages. ```python # Wait for element presence (not necessarily clickable) error_div = page_actions.get_presence_element( "//div[@class='rc-imageselect-incorrect-response']", timeout=10 ) print(error_div.is_displayed()) ``` -------------------------------- ### PageActions.click_check_button Source: https://context7.com/2captcha/selenium-recaptcha-solver-using-grid/llms.txt Clicks a target button, such as the verify, reload, or submit button. It includes a short delay and waits for the button to be clickable before performing the click. ```APIDOC ## PageActions.click_check_button — Click the verify/reload/submit button Waits 1 second, then waits for the target button to be clickable and clicks it. Used for the captcha verify button, the reload button, and the page submit button. ```python c_verify_button = "//button[@id='recaptcha-verify-button']" c_reload_button = "//button[@id='recaptcha-reload-button']" p_submit_button_captcha = "//button[@type='submit']" # After selecting image tiles, press verify page_actions.click_check_button(c_verify_button) # Output: "Pressed the Check button" # If too many errors occur, reload the captcha page_actions.click_check_button(c_reload_button) # After the captcha is fully solved, submit the page form page_actions.switch_to_default_content() page_actions.click_check_button(p_submit_button_captcha) ``` ``` -------------------------------- ### Wait for Clickable Element Source: https://context7.com/2captcha/selenium-recaptcha-solver-using-grid/llms.txt Waits up to a specified timeout for an element to become clickable in the DOM. Returns the WebElement once it's clickable. Used here to interact with the verify button. ```python # Wait up to 30 s for an element to be clickable verify_btn = page_actions.get_clickable_element( "//button[@id='recaptcha-verify-button']", timeout=30 ) verify_btn.click() ``` -------------------------------- ### PageActions.clicks Source: https://context7.com/2captcha/selenium-recaptcha-solver-using-grid/llms.txt Clicks specific image tile cells within the reCAPTCHA grid based on a list of zero-based indices. This is used to submit the answer provided by the 2Captcha service. ```APIDOC ## PageActions.clicks — Click image tile cells by index Iterates over a list of zero-based cell indices and clicks the corresponding `` elements in the reCAPTCHA image grid. Used to submit the answer returned by 2Captcha. ```python # answer_list is a list of 0-based cell indices (e.g., cells 0, 2, 5 in a 3x3 grid) answer_list = [0, 2, 5] page_actions.clicks(answer_list) # Clicks , , in the captcha table # Output: "Cells are marked" ``` ``` -------------------------------- ### CaptchaHelper.handle_error_messages Source: https://context7.com/2captcha/selenium-recaptcha-solver-using-grid/llms.txt Checks for the visibility of four different captcha error messages sequentially using `is_message_visible`. It returns `True` immediately if any error message is found, indicating that the solve loop should retry. If no error messages are visible, it returns `False`, signifying it is safe to proceed with submission. ```APIDOC ## `CaptchaHelper.handle_error_messages` — Check all captcha error messages at once Checks four error-message locators in sequence using `is_message_visible`. Returns `True` as soon as any one is visible, signalling the solve loop to retry. Returns `False` if none are visible (safe to submit). ```python c_try_again = "//div[@class='rc-imageselect-incorrect-response']" c_select_more = "//div[@class='rc-imageselect-error-select-more']" c_dynamic_more = "//div[@class='rc-imageselect-error-dynamic-more']" c_select_something = "//div[@class='rc-imageselect-error-select-something']" has_error = captcha_helper.handle_error_messages( c_try_again, c_select_more, c_dynamic_more, c_select_something ) ``` ``` -------------------------------- ### Poll for Captcha Tile Replacement Requests Source: https://context7.com/2captcha/selenium-recaptcha-solver-using-grid/llms.txt Polls for network requests indicating captcha tile replacements. It returns True if the expected number of updates are detected within the specified retries and wait time, otherwise False. Useful for continuing the solving loop or proceeding to verification. ```python # 3x3: wait for exactly as many tile replacements as tiles clicked page_actions.reset_image_update_flag() page_actions.clicks([0, 3, 6]) image_update = page_actions.check_for_image_updates( expected_updates=3, # 3 tiles clicked → expect 3 replacement requests wait_time=0.5, retries=10 ) if image_update: print("New tiles loaded — continue solving loop") # Output: "Images updated (network requests detected)" else: print("No new tiles — proceed to verify") # Output: "No image updates detected" # 4x4: any update activity is sufficient (no expected_updates count needed) image_update = page_actions.check_for_image_updates() ``` -------------------------------- ### Parse 2Captcha Grid Answer to Click Indices Source: https://context7.com/2captcha/selenium-recaptcha-solver-using-grid/llms.txt Converts the 2Captcha response string (e.g., 'OK:1/3/7') into a zero-based list of integer cell indices. This is useful for passing to `PageActions.clicks()`, as 2Captcha uses 1-based indices. ```python answer = "OK:1/3/7" number_list = captcha_helper.pars_answer(answer) # Output: "Parsed the response to a list of cell numbers" print(number_list) # [0, 2, 6] ← converted from 1-based to 0-based # Another example answer2 = "OK:2/5/8/11" number_list2 = captcha_helper.pars_answer(answer2) print(number_list2) # [1, 4, 7, 10] # Pass directly to clicks() page_actions.clicks(number_list) ``` -------------------------------- ### monitorRequests / resetImageUpdateFlag Source: https://context7.com/2captcha/selenium-recaptcha-solver-using-grid/llms.txt JavaScript functions injected by `track_image_updates.js` to monitor tile replacements in reCAPTCHA. `resetImageUpdateFlag()` clears counters, and `monitorRequests(n)` returns true when at least `n` replacement requests have been observed. ```APIDOC ## `monitorRequests(expectedCount)` / `resetImageUpdateFlag()` — JavaScript: Track tile replacements Injected by `track_image_updates.js`. Patches `window.fetch` and `XMLHttpRequest.prototype.open` to intercept calls to `recaptcha/api2/replaceimage`. `resetImageUpdateFlag()` clears counters; `monitorRequests(n)` returns `true` when at least `n` replacement requests have been observed since the last reset. ```javascript // Inject track_image_updates.js once, then use these functions from Python: // Before clicking tiles, reset the counter resetImageUpdateFlag(); // window.__recaptchaReplaceImageCount = 0 // ... selenium clicks 3 tiles ... // Poll: returns true when 3 replaceimage requests have been seen const updated = monitorRequests(3); // true | false // Without argument: returns true if any replaceimage was seen const anyUpdate = monitorRequests(); // From Python via Selenium: // updated = browser.execute_script("return monitorRequests(arguments[0]);", 3) ``` ``` -------------------------------- ### PageActions.get_presence_element Source: https://context7.com/2captcha/selenium-recaptcha-solver-using-grid/llms.txt Waits for an element to be present in the DOM within a specified timeout. ```APIDOC ## PageActions.get_presence_element ### Description Low-level helper that uses `WebDriverWait` to wait up to `timeout` seconds for an element to be present in the DOM. Returns the located WebElement. ### Method ```python page_actions.get_presence_element("//div[@class='rc-imageselect-incorrect-response']", timeout=10) ``` ### Parameters * **locator** (str) - The locator string for the element. * **timeout** (int, optional) - The maximum time in seconds to wait for the element to be present. Defaults to None. ### Response * **WebElement**: The located WebElement. ### Request Example ```python # Wait for element presence (not necessarily clickable) error_div = page_actions.get_presence_element( "//div[@class='rc-imageselect-incorrect-response']", timeout=10 ) print(error_div.is_displayed()) ``` ``` -------------------------------- ### Solve reCAPTCHA Grid Challenges with Python Source: https://context7.com/2captcha/selenium-recaptcha-solver-using-grid/llms.txt Submit base64-encoded captcha images to the 2Captcha grid API. This function handles parameters like grid dimensions, instruction text, and language. It returns a result dictionary with `captchaId` and `code`, or indicates unsolvable or error states. ```python captcha_data = browser.execute_script("return getCaptchaData();") params = { "method": "base64", "img_type": "recaptcha", "recaptcha": 1, "cols": captcha_data['columns'], # 3 or 4 "rows": captcha_data['rows'], # 3 or 4 "textinstructions": captcha_data['comment'], # e.g. "Select all traffic lights" "lang": "en", "can_no_answer": 1, } # For 3x3 subsequent iterations, pass previousID to speed up solving if params['cols'] == 3 and saved_id: params["previousID"] = saved_id result = captcha_helper.solver_captcha(file=captcha_data['body'], **params) # Output: "Captcha solved" # Possible return values: # Success: {'captchaId': '61234567890', 'code': 'OK:1/3/7'} # No match: {'captchaId': '61234567891', 'code': 'OK:No_matching_images'} # Unsolvable: {'unsolvable': True} # Error: None if result is None: print("Fatal error — stop") elif result.get("unsolvable"): print("Unsolvable — retry same image") elif 'No_matching_images' in result['code']: print("No matching tiles — click verify and check for errors") else: print(f"Solved: {result['code']}") # e.g. "OK:1/3/7" saved_id = result['captchaId'] # Save for 3x3 previousID ``` -------------------------------- ### PageActions.reset_image_update_flag Source: https://context7.com/2captcha/selenium-recaptcha-solver-using-grid/llms.txt Resets the JavaScript image-update observation window by calling the `resetImageUpdateFlag()` function. This prepares for monitoring new image updates after clicks. ```APIDOC ## PageActions.reset_image_update_flag — Reset the JS image-update observation window Calls the `resetImageUpdateFlag()` JavaScript function (injected by `track_image_updates.js`) to clear the network request counters and start a fresh observation window before new clicks are made. ```python # Example usage (assuming page_actions is initialized and in the correct iframe): # page_actions.reset_image_update_flag() ``` ``` -------------------------------- ### PageActions.reset_image_update_flag Source: https://context7.com/2captcha/selenium-recaptcha-solver-using-grid/llms.txt Resets the image update flag to ensure subsequent checks only count new requests. ```APIDOC ## PageActions.reset_image_update_flag ### Description Resets the image update flag. This should be called before performing clicks so that the subsequent `check_for_image_updates()` only counts requests from the new click batch. ### Method ``` page_actions.reset_image_update_flag() ``` ### Output ``` Reset image update flag ``` ``` -------------------------------- ### Handle Multiple reCAPTCHA Error Messages at Once Source: https://context7.com/2captcha/selenium-recaptcha-solver-using-grid/llms.txt Checks for the visibility of four common captcha error messages sequentially using `is_message_visible`. Returns `True` immediately if any error message is found, indicating the solve loop should retry. Returns `False` if no errors are detected. ```python c_try_again = "//div[@class='rc-imageselect-incorrect-response']" c_select_more = "//div[@class='rc-imageselect-error-select-more']" c_dynamic_more = "//div[@class='rc-imageselect-error-dynamic-more']" c_select_something = "//div[@class='rc-imageselect-error-select-something']" has_error = captcha_helper.handle_error_messages( c_try_again, c_select_more, c_dynamic_more, c_select_something ) ``` -------------------------------- ### JavaScript: Extract Captcha Image Data Source: https://context7.com/2captcha/selenium-recaptcha-solver-using-grid/llms.txt This JavaScript function, injected into the captcha iframe, extracts captcha details including dimensions, type, instruction text, and the captcha image encoded as a base64 JPEG string. It handles both 3x3 and 4x4 grids. ```javascript // After injecting get_captcha_data.js, call from Python or browser console: const data = getCaptchaData(); // Returned object structure: // { // rows: 3, // or 4 // columns: 3, // or 4 // type: 'GridTask', // comment: 'Select all images with bicycles', // instruction text // body: '/9j/4AAQSkZJRgAB...' // base64 JPEG, no data URI prefix // } // For 3x3: composites base 3x3 image + any rc-image-tile-11 overlay tiles // For 4x4: captures the single rc-image-tile-44 image directly console.log(`Grid: ${data.rows}x${data.columns}`); console.log(`Instruction: ${data.comment}`); console.log(`Image length: ${data.body.length} chars`); ``` -------------------------------- ### Handle reCAPTCHA Errors and Submit Form Source: https://context7.com/2captcha/selenium-recaptcha-solver-using-grid/llms.txt This code block handles specific reCAPTCHA errors by incrementing error counts and retrying the captcha. If no errors occur, it proceeds to submit the form. ```python if has_error: # Determine which specific error occurred for targeted handling if captcha_helper.is_message_visible(c_select_something): select_something_errors += 1 if select_something_errors >= 2: page_actions.click_check_button("//button[@id='recaptcha-reload-button']") continue # Restart the solving loop else: # No errors — safe to submit the form page_actions.switch_to_default_content() page_actions.click_check_button("//button[@type='submit']") break ``` -------------------------------- ### CaptchaHelper.is_message_visible Source: https://context7.com/2captcha/selenium-recaptcha-solver-using-grid/llms.txt Checks the visibility of a captcha error element using its XPath locator. It employs inline JavaScript's `getComputedStyle` to determine if the element is visually apparent (not hidden by `display:none`, `visibility:hidden`, or `opacity:0`). Returns `True` or `False`. ```APIDOC ## `CaptchaHelper.is_message_visible` — Check visibility of a captcha error element Locates an element by XPath and uses an inline JavaScript `getComputedStyle` check to determine whether it is visually visible (not `display:none`, `visibility:hidden`, or `opacity:0`). Returns `True` or `False`. ```python c_try_again = "//div[@class='rc-imageselect-incorrect-response']" c_select_more = "//div[@class='rc-imageselect-error-select-more']" c_select_something = "//div[@class='rc-imageselect-error-select-something']" if captcha_helper.is_message_visible(c_try_again): print("'Please try again' is showing — retry") if captcha_helper.is_message_visible(c_select_more): print("'Please select all matching images' is showing") if captcha_helper.is_message_visible(c_select_something): print("'Please select something' is showing") ``` ``` -------------------------------- ### Check reCAPTCHA Error Message Visibility Source: https://context7.com/2captcha/selenium-recaptcha-solver-using-grid/llms.txt Determines if a captcha error element is visually present using XPath and an inline JavaScript `getComputedStyle` check. Returns `True` if visible (not `display:none`, `visibility:hidden`, or `opacity:0`), `False` otherwise. ```python c_try_again = "//div[@class='rc-imageselect-incorrect-response']" c_select_more = "//div[@class='rc-imageselect-error-select-more']" c_select_something = "//div[@class='rc-imageselect-error-select-something']" if captcha_helper.is_message_visible(c_try_again): print("'Please try again' is showing — retry") if captcha_helper.is_message_visible(c_select_more): print("'Please select all matching images' is showing") if captcha_helper.is_message_visible(c_select_something): print("'Please select something' is showing") ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.