Aller au contenu
ÉtatTableau de bord

Guides

Clic automatique sur les images reCAPTCHA v2 avec Selenium

Cette page a été traduite automatiquement à partir de la version chinoise et peut contenir des erreurs. La version chinoise fait foi.

Ce tutoriel ouvre la page de démonstration reCAPTCHA de Google avec Selenium 4 et résout l’épreuve d’images dans un vrai navigateur : il lit la question et l’image, demande à la reconnaissance d’images reCAPTCHA v2 (ReCaptchaV2Classification) quelles cases cliquer, puis simule les clics. Contrairement à la méthode par token, la vérification se fait réellement dans le navigateur, ce qui convient aux sites où le taux de réussite des tokens est faible.

Si vous ne voulez pas écrire de code, utilisez directement l’extension de navigateur : elle clique automatiquement via le même endpoint.

pip install requests selenium pillow
export YESCAPTCHA_CLIENT_KEY=your_client_key

Chrome doit être installé. Selenium 4 télécharge automatiquement le chromedriver correspondant.

  1. Cliquez sur la case à cocher. Elle se trouve dans l’iframe title="reCAPTCHA" : basculez dedans, puis cliquez sur #recaptcha-anchor.
  2. Basculez vers l’iframe de l’épreuve. L’épreuve se trouve dans une autre iframe (dont le title contient « challenge »).
  3. Lisez la question. Le texte en gras dans .rc-imageselect-desc-wrapper strong est la cible à trouver, par exemple « traffic lights ». L’API attend l’ID de la question : convertissez le nom en ID (/m/015qff) avec la table de correspondance, voir ID de question. L’interface du navigateur en anglais est la plus pratique pour la comparaison.
  4. Récupérez l’image. Les images des cases sont en fait une seule grande image : téléchargez le src de td.rc-imageselect-tile img. Redimensionnez à 300×300 pour 9 cases (3x3) ou à 450×450 pour 16 cases (4x4), puis encodez en Base64.
  5. Reconnaissance. Appelez createTask avec le type ReCaptchaV2Classification, en passant image et question. Avec "confidence": 0.5, les images 3x3 renvoient toutes les cases correspondantes en une seule fois : il n’y a plus à traiter les petites images qui apparaissent après les clics.
  6. Cliquez. Les objects renvoyés sont des numéros de cases, à partir de 0, de gauche à droite et de haut en bas ; cliquez sur les td correspondants dans l’ordre.
  7. Vérifiez. Cliquez sur #recaptcha-verify-button. Si une nouvelle série d’images apparaît, revenez à l’étape 3 ; si la fenêtre de l’épreuve se ferme, c’est réussi.
  8. Envoyez le formulaire. Revenez à la page principale et cliquez sur le bouton d’envoi.
recaptcha_click_selenium.py
"""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.py
Each recognized image is charged (see the price list). reCAPTCHA's page structure can change;
adjust the selectors below if a step stops working.
"""
import base64
import io
import os
import time
import requests
from PIL import Image
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from 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 structure de la page reCAPTCHA change au fil du temps : si les sélecteurs du code ne fonctionnent plus, adaptez-les à la page réelle.
  • Chaque image reconnue entraîne un débit de points (tarifs sur reCAPTCHA v2 reconnaissance d’images). Les tâches dont la vérification a échoué après les clics peuvent être signalées dans l’heure qui suit pour demander un remboursement après signalement.
  • Si la question ne figure pas dans la table de correspondance, cliquez sur le bouton de rechargement pour obtenir une autre épreuve, ou contactez le support pour demander l’ajout de cette question.