Guías
Clics simulados en reCAPTCHA v2 con reconocimiento de imágenes (Selenium)
Esta página se tradujo automáticamente de la versión en chino y puede contener errores. Prevalece la versión en chino.
Este tutorial abre la página de demostración de reCAPTCHA de Google con Selenium 4 y resuelve el desafío de imágenes en un navegador real: lee la pregunta y la imagen, se las envía a reconocimiento de imágenes de reCAPTCHA v2 (ReCaptchaV2Classification) para saber en qué casillas hacer clic, y luego simula los clics. A diferencia del enfoque con token, la verificación se completa en el propio navegador, lo que es útil en sitios donde los tokens rara vez pasan.
Si no quieres escribir código, usa directamente la extensión del navegador, que hace lo mismo con la misma API.
Preparación
Sección titulada «Preparación»pip install requests selenium pillowexport YESCAPTCHA_CLIENT_KEY=your_client_keyNecesitas tener Chrome instalado. Selenium 4 descarga automáticamente el chromedriver compatible.
- Haz clic en la casilla. La casilla está dentro del iframe con
title="reCAPTCHA": cambia a ese iframe y haz clic en#recaptcha-anchor. - Cambia al iframe del desafío. El desafío está en otro iframe (cuyo title contiene “challenge”).
- Lee la pregunta. El texto en negrita de
.rc-imageselect-desc-wrapper stronges el objetivo, por ejemplo “traffic lights”. La API necesita el ID de la pregunta, así que usa la tabla de equivalencias para convertir el nombre en un ID (/m/015qff); consulta ID de pregunta. Es más fácil comparar si la interfaz del navegador está en inglés. - Obtén la imagen. Las casillas son en realidad fragmentos de una misma imagen grande: descarga el
srcdetd.rc-imageselect-tile img. Con 9 casillas (3x3) escálala a 300×300 y con 16 casillas (4x4) a 450×450, y conviértela a Base64. - Reconoce. Llama a
createTaskcon el tipoReCaptchaV2Classificationy envíaimageyquestion. Si añades"confidence": 0.5, las imágenes 3x3 devuelven de una vez todas las casillas que coinciden, y no tienes que gestionar las imágenes pequeñas que aparecen tras hacer clic. - Haz clic.
objectscontiene los índices de las casillas, empezando en 0, de izquierda a derecha y de arriba abajo; haz clic en lostdcorrespondientes en ese orden. - Verifica. Haz clic en
#recaptcha-verify-button. Si aparece una nueva ronda, vuelve al paso 3; cuando la ventana del desafío se cierra, has pasado. - Envía el formulario. Vuelve a la página principal y haz clic en el botón de envío.
Código completo
Sección titulada «Código completo»"""Click through a reCAPTCHA v2 image challenge with Selenium 4 and ReCaptchaV2Classification.
Flow: open the page -> click the checkbox -> read the target name and the grid image ->ask YesCaptcha which tiles to click -> click them -> press Verify. Repeat if a new challenge appears.
Run: pip install requests selenium pillow export YESCAPTCHA_CLIENT_KEY=your_client_key python recaptcha_click_selenium.pyEach recognized image is charged (see the price list). reCAPTCHA's page structure can change;adjust the selectors below if a step stops working."""import base64import ioimport osimport time
import requestsfrom PIL import Imagefrom selenium import webdriverfrom selenium.webdriver.common.by import Byfrom selenium.webdriver.support import expected_conditions as ECfrom selenium.webdriver.support.wait import WebDriverWait
CLIENT_KEY = os.environ["YESCAPTCHA_CLIENT_KEY"]PAGE_URL = "https://www.google.com/recaptcha/api2/demo"
# Target names shown in the challenge (English UI) -> question IDs.# Full list: https://docs.yescaptcha.com/en/tasks/recaptcha-classification/QUESTION_IDS = { "taxis": "/m/0pg52", "bus": "/m/01bjv", "buses": "/m/01bjv", "motorcycles": "/m/04_sv", "tractors": "/m/013xlm", "chimneys": "/m/01jk_4", "crosswalks": "/m/014xcs", "traffic lights": "/m/015qff", "bicycles": "/m/0199g", "parking meters": "/m/015qbp", "cars": "/m/0k4j", "bridges": "/m/015kr", "boats": "/m/019jd", "palm trees": "/m/0cdl1", "mountains or hills": "/m/09d_r", "fire hydrants": "/m/01pns0", "a fire hydrant": "/m/01pns0", "stairs": "/m/01lynh",}
def classify(image_b64, question): task = {"type": "ReCaptchaV2Classification", "image": image_b64, "question": question, "confidence": 0.5} data = requests.post( "https://api.yescaptcha.com/createTask", json={"clientKey": CLIENT_KEY, "task": task}, timeout=30, ).json() if data.get("errorId"): raise RuntimeError(f"{data.get('errorCode')}: {data.get('errorDescription')}") return data["solution"] # synchronous: the solution comes back right away
def grid_image_b64(url, size): """Download the challenge image and scale it to the standard size (300 for 3x3, 450 for 4x4).""" img = Image.open(io.BytesIO(requests.get(url, timeout=30).content)).convert("RGB") img = img.resize((size, size)) buf = io.BytesIO() img.save(buf, format="JPEG") return base64.b64encode(buf.getvalue()).decode()
driver = webdriver.Chrome()wait = WebDriverWait(driver, 15)try: driver.get(PAGE_URL)
# 1. Click the checkbox (inside the "reCAPTCHA" iframe) wait.until(EC.frame_to_be_available_and_switch_to_it((By.CSS_SELECTOR, 'iframe[title="reCAPTCHA"]'))) wait.until(EC.element_to_be_clickable((By.ID, "recaptcha-anchor"))).click() driver.switch_to.default_content()
# 2. Switch to the challenge iframe and solve rounds until it closes wait.until(EC.frame_to_be_available_and_switch_to_it( (By.XPATH, '//iframe[contains(@title, "challenge")]'))) for _ in range(5): target = wait.until(EC.presence_of_element_located( (By.CSS_SELECTOR, ".rc-imageselect-desc-wrapper strong"))).text.strip().lower() question = QUESTION_IDS.get(target) if not question: print("unsupported target, reloading:", target) driver.find_element(By.ID, "recaptcha-reload-button").click() time.sleep(2) continue tiles = driver.find_elements(By.CSS_SELECTOR, "td.rc-imageselect-tile") size = 450 if len(tiles) == 16 else 300 url = driver.find_element(By.CSS_SELECTOR, "td.rc-imageselect-tile img").get_attribute("src") solution = classify(grid_image_b64(url, size), question) for index in solution.get("objects", []): tiles[index].click() time.sleep(0.3) time.sleep(1) driver.find_element(By.ID, "recaptcha-verify-button").click() time.sleep(3) driver.switch_to.default_content() frame = driver.find_element(By.XPATH, '//iframe[contains(@title, "challenge")]') if not frame.is_displayed(): # challenge closed: passed break driver.switch_to.frame(frame)
driver.switch_to.default_content() driver.find_element(By.ID, "recaptcha-demo-submit").click() time.sleep(2) print("passed" if "Verification Success" in driver.page_source else "not passed")finally: driver.quit()- La estructura de la página de reCAPTCHA cambia con el tiempo; si los selectores del código dejan de funcionar, ajústalos a la página real.
- Cada imagen reconocida implica un cobro de puntos (precios en reconocimiento de imágenes de reCAPTCHA v2). Las tareas cuyo clic fue rechazado se pueden reportar en un plazo de 1 hora para solicitar el reembolso tras reportar.
- Si encuentras una pregunta que no está en la tabla de equivalencias, haz clic en el botón de recarga para obtener otra, o contacta con Soporte para que añadan compatibilidad.