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.
Préparation
Section intitulée « Préparation »pip install requests selenium pillowexport YESCAPTCHA_CLIENT_KEY=your_client_keyChrome doit être installé. Selenium 4 télécharge automatiquement le chromedriver correspondant.
- Cliquez sur la case à cocher. Elle se trouve dans l’iframe
title="reCAPTCHA": basculez dedans, puis cliquez sur#recaptcha-anchor. - Basculez vers l’iframe de l’épreuve. L’épreuve se trouve dans une autre iframe (dont le title contient « challenge »).
- Lisez la question. Le texte en gras dans
.rc-imageselect-desc-wrapper strongest 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. - Récupérez l’image. Les images des cases sont en fait une seule grande image : téléchargez le
srcdetd.rc-imageselect-tile img. Redimensionnez à 300×300 pour 9 cases (3x3) ou à 450×450 pour 16 cases (4x4), puis encodez en Base64. - Reconnaissance. Appelez
createTaskavec le typeReCaptchaV2Classification, en passantimageetquestion. 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. - Cliquez. Les
objectsrenvoyés sont des numéros de cases, à partir de 0, de gauche à droite et de haut en bas ; cliquez sur lestdcorrespondants dans l’ordre. - 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. - Envoyez le formulaire. Revenez à la page principale et cliquez sur le bouton d’envoi.
Code complet
Section intitulée « Code complet »"""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()Remarques
Section intitulée « Remarques »- 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.