I'm trying to solve a ReCAPTCHA v2 challenge using CapSolver with the ReCaptchaV2Classification task type.
However, whenever I call the CapSolver API, the response is always false, and the images are not being selected, so the CAPTCHA is never solved.
I've followed the official documentation but still can't get it to work.Any help or guidance would be greatly appreciated.
import timeimport base64import requestsimport osfrom selenium import webdriverfrom selenium.webdriver.chrome.options import Optionsfrom selenium.webdriver.support.ui import WebDriverWaitfrom selenium.webdriver.common.by import Byfrom selenium.webdriver.support import expected_conditions as ECfrom selenium.webdriver.chrome.service import Servicefrom webdriver_manager.chrome import ChromeDriverManagerCAPSOLVER_API_KEY = 'CAP-0000'# Basic PT → EN translator for reCAPTCHA questionsWORD_TRANSLATOR = {"ônibus": "/m/01bjv", # bus"ônibus escolar": "/m/02yvhj", # school bus"semáforos": "/m/015qff", # traffic lights"faixas de pedestre": "/m/014xcs", # crosswalks"carros": "/m/0k4j", # cars"motocicletas": "/m/04_sv", # motorcycles"hidrante": "/m/01pns0", # fire hydrant"placas de trânsito": "/m/015qbp", # parking meters"escadas": "/m/01lynh", # stairs"bicicletas": "/m/0199g", # bicycles"tratores": "/m/013xlm", # tractors"táxis": "/m/0pg52", # taxis"cruzamentos": "/m/015kr", # bridges"barcos": "/m/019jd", # boats"palmeiras": "/m/0cdl1", # palm trees"montanhas": "/m/09d_r", # mountains or hills"chaminés": "/m/01jk_4", # chimneys}def translate_question(text): for pt, en in WORD_TRANSLATOR.items(): if pt in text: return en return "" # fallbackdef launch_browser(): options = Options() options.add_argument("--disable-blink-features=AutomationControlled") options.add_experimental_option("excludeSwitches", ["enable-automation"]) options.add_argument("start-maximized") options.add_argument("--no-sandbox") options.add_argument("--disable-dev-shm-usage") options.add_experimental_option("detach", True) root_path = os.path.dirname(os.path.abspath(__file__)) extension_path = os.path.join(root_path, "PGOJNOJMMHPOFJGDMAEBADHBOCAHPPOD_1_15_5_0.crx") options.add_extension(extension_path) driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()), options=options) driver.set_page_load_timeout(60) return driverdef click_checkbox(driver): WebDriverWait(driver, 10).until( EC.frame_to_be_available_and_switch_to_it((By.XPATH, "//iframe[contains(@src, 'anchor')]")) ) WebDriverWait(driver, 10).until( EC.element_to_be_clickable((By.ID, "recaptcha-anchor")) ).click() driver.switch_to.default_content()def capture_question(driver): try: driver.switch_to.default_content() WebDriverWait(driver, 10).until( EC.frame_to_be_available_and_switch_to_it((By.XPATH, "//iframe[contains(@src, 'bframe')]")) ) strong = WebDriverWait(driver, 5).until( EC.presence_of_element_located((By.CSS_SELECTOR, ".rc-imageselect-desc-wrapper strong")) ) text = strong.text.strip().lower() print(f"🧠 Captured question: {text}") if "ônibus" in text: if "escolar" in text: return "/m/02yvhj" else: return "/m/01bjv" for pt, code in WORD_TRANSLATOR.items(): if pt in text: print(f"🔎 Matched term: '{pt}'→ code {code}") return code print("⚠️ No matching term found.") return "" except Exception as e: print("❌ Error capturing question:", e) return ""def take_grid_screenshot(driver, path='grid.png'): try: driver.switch_to.default_content() WebDriverWait(driver, 10).until( EC.frame_to_be_available_and_switch_to_it((By.XPATH, "//iframe[contains(@src, 'bframe')]")) ) grid_container = WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.ID, "rc-imageselect-target")) ) grid_container.screenshot(path) print(f"📸 Screenshot saved: {path}") except Exception as e: print(f"❌ Error taking grid screenshot: {e}") raisedef image_to_base64(path): with open(path, 'rb') as img: return base64.b64encode(img.read()).decode('utf-8')def solve_with_capsolver(image_b64, question_en): url = "https://api.capsolver.com/createTask" print('question:', question_en) payload = {"clientKey": CAPSOLVER_API_KEY,"task": {"type": "ReCaptchaV2Classification","image": image_b64,"question": question_en } } response = requests.post(url, json=payload) result = response.json() print(f"📬 CapSolver response: {result}") solution = result.get('solution', {}) return solution.get('objects', []), solution.get('hasObject', False)def click_images(driver, indices): images = driver.find_elements(By.CSS_SELECTOR, "td img") print(f"Images found: {len(images)} - clicking indices: {indices}") tds = driver.find_elements(By.CSS_SELECTOR, "table.rc-imageselect-table td") for i in indices: if i < len(tds): try: tds[i].click() time.sleep(0.4) except: passdef is_challenge_active(driver): try: return driver.find_element(By.CSS_SELECTOR, "div.rc-imageselect") is not None except: return Falsedef solve_recaptcha(driver): driver.get("https://www.google.com/recaptcha/api2/demo") click_checkbox(driver) attempt = 1 while True: print(f"[{attempt}] Attempting to solve challenge...") try: question_en = capture_question(driver) if not question_en: print("❌ Invalid or unrecognized question.") break take_grid_screenshot(driver, 'grid.png') base64_img = image_to_base64('grid.png') indices, has_object = solve_with_capsolver(base64_img, question_en) images = driver.find_elements(By.CSS_SELECTOR, "td img") print(f"Images found: {len(images)}") if len(images) > 9: print("⚠️ Grid with more than 9 images detected. Reloading.") driver.find_element(By.ID, "recaptcha-reload-button").click() time.sleep(2) attempt += 1 continue if not has_object: print("🤖 No object detected. Clicking 'Skip' and retrying.") driver.find_element(By.ID, "recaptcha-reload-button").click() time.sleep(2) attempt += 1 continue click_images(driver, indices) try: verify_btn = WebDriverWait(driver, 2).until( EC.element_to_be_clickable((By.ID, "recaptcha-verify-button")) ) verify_btn.click() print("🟢'Verify' button clicked.") except: print("🔄'Verify' button not visible yet.") time.sleep(3) driver.switch_to.default_content() WebDriverWait(driver, 10).until( EC.frame_to_be_available_and_switch_to_it((By.XPATH, "//iframe[contains(@src, 'bframe')]")) ) if not is_challenge_active(driver): print("✅ reCAPTCHA solved successfully!") break except Exception as e: print(f"❌ Error during solving process: {e}") break attempt += 1 time.sleep(1)def main(): driver = launch_browser() solve_recaptcha(driver)if __name__ == "__main__": main()📬 CapSolver response: {'errorId': 0, 'status': 'ready', 'solution': {'hasObject': False, 'size': 0, 'type': ''}, 'taskId': '<task_id>'}






