Як я обійшов Slide CAPTCHA за допомогою Computer Vision and Selenium
Мене звати Дмитро, я займаюсь збором даних з інтернету та автоматизацією процесів, пов’язаних з цим.
Також мене захоплює комп’ютерний зір і його здатність розв’язувати складні проблеми. Думав над тим, як його можна використати у веб-скрапінгу — не тільки для парсингу таблиць чи витягування тексту з зображень, але й для обходу захисту від ботів на вебсайтах. Ідея «боти проти ботів» здається водночас кумедною та трохи страшною...
Я почав шукати модель, яка могла б допомогти обійти CAPTCHA, і після деяких досліджень знайшов одну, яка здалася перспективною. Більше про цю модель можна прочитати тут. Тепер перейдемо до кроків, які я зробив, і того, що я отримав.
1. Знайти сайт з CAPTCHA та завантажити модель
Я знайшов сайт для тестування рішення CAPTCHA: цей демонстраційний проєкт на CodePen. Щодо моделі, яку я використовую, можна прочитати більше тут. Для управління рухами миші під час слайдінгу я використовую клас Controller з бібліотеки pynput.mouse, яка надає точне керування курсором.
Пропущу кроки налаштування залежностей, оскільки нічого надзвичайного не використовував. Але якщо вам потрібні деталі, не соромтесь питати в коментарях!
Код для цього кроку:
import math import random from time import sleep from selenium import webdriver from selenium.webdriver.common.by import By from pynput.mouse import Button, Controller from ultralytics import YOLO CAPTCHA_URL = "https://2captcha.com/demo/geetest" mouse = Controller()
2. Відкрити браузер, перейти за URL CAPTCHA і натиснути на кнопку CAPTCHA
Наступним кроком є відкриття браузера та перехід за URL CAPTCHA_URL. Крок простий, тому не будемо витрачати на нього багато часу.
driver = webdriver.Firefox() driver.maximize_window() driver.get(CAPTCHA_URL) sleep(10) try: btn = driver.find_element(By.CLASS_NAME, "geetest_radar_btn") btn.click() sleep(3) # Wait for CAPTCHA to load except Exception as e: raise Exception("CAPTCHA button was not found!") from e
3. Знайти та зберегти зображення CAPTCHA
Далі ми знаходимо елемент зображення CAPTCHA на сторінці та зберігаємо його як файл. Це зображення ми використаємо з нашою моделлю для обчислення відстані між шматочками пазла.
element = driver.find_element(By.CLASS_NAME, "geetest_fullpage_click_box") captcha_file_name = "geetest_canvas_slice.png" element.screenshot(captcha_file_name) sleep(3)
4. Обчислити відстань між шматочками пазла
На цьому етапі ми використовуємо нашу навчену модель для передбачення положень шматочків пазла, що дає змогу обчислити відстань між ними.
results = model.predict( source=captcha_file_name, device='cpu', conf=0.8, imgsz=[416, 416], ) box_with_max_conf = max(results, key=lambda x: x.boxes.conf.max()) box_with_conf = box_with_max_conf.boxes.data.tolist()
Якщо перевірити box_with_conf, ви побачите список списків. Кожен список містить дані про шматочок пазла, де 0.0 в кінці позначає тіньовий шматочок, а 2.0 — оригінальний шматочок. Наприклад:
[[141.16949462890625, 117.8351058959961, 199.66102600097656, 166.53150939941406, 0.9436098337173462, 0.0], [13.732378959655762, 117.82501220703125, 73.385498046875, 165.75665283203125, 0.9163503646850586, 2.0]]
Далі ми позначаємо ці шматочки та обчислюємо відстань між ними.
# Ensure we have both pieces identified by the model assert len(box_with_conf) == 2, "Found only one piece of puzzle!" shadow = [el for el in box_with_conf if el[-1] == 0.0][0] origin = [el for el in box_with_conf if el[-1] != 0.0][0] # Calculate the horizontal distance, adjusting for resolution difference distance = (shadow[0] - origin[0])*0.791
Застосовуємо коефіцієнт масштабування (0.791), щоб врахувати різницю в розмірах між збереженим знімком екрана та вхідним розміром моделі (швидше за все у вас він буде інший).
5. Перемістити мишу на кнопку слайдера і натискати
На цьому етапі ми знаходимо кнопку слайдера, обчислюємо її позицію і потім переміщаємо мишу на неї, щоб симулювати натискання.
# Locate the slider button and get its location and size slider = driver.find_element(By.CLASS_NAME, "geetest_slider_button") location = slider.location size = slider.size # Calculate the start position (center of the button, slightly adjusted for accuracy) start_x = location['x'] + size['width'] / 2 start_y = location['y'] + size['height'] * 2 # Adjust to a better starting point for clicking sleep(1) mouse.press(Button.left)
6. Порахувати значення для кожного кроку
Хоча й без цієї додаткової логіки все має працювати, я подумав, що було б більш схоже на людську поведінку, якщо рухи починатимуться швидше і згодом сповільнюватимуться. Це досягається шляхом обчислення кроків за допомогою геометричної прогресії, що симулює більш плавний, природний рух.
def geometric_progression_steps(initial_value, threshold=1e-12): if initial_value <= 0: raise ValueError("Initial value must be positive") if threshold <= 0: raise ValueError("Threshold must be positive") steps = math.ceil((math.log(threshold) - math.log(initial_value)) / math.log(0.5)) current_value = initial_value values_per_step = [] for _ in range(steps): current_value /= 2 values_per_step.append(current_value) return values_per_step # Calculate the values for each step based on the distance values_per_step = geometric_progression_steps(distance)
7. Останній крок: перемістити пазл
В останньому кроці виконуємо рух миші для вирішення CAPTCHA. Додаючи значення з values_per_step до початкової позиції, ми симулюємо рух слайдера. Використовуємо випадкову затримку, щоб рухи були більш схожі на людські.
# Move the puzzle piece by adjusting the position with values from the progression for value in values_per_step[:]: start_x += value # Move horizontally by the current step value # Set the mouse position to the new coordinates mouse.position = (start_x, start_y) # Add a slight delay between movements to mimic human interaction sleep(random.uniform(0.05, 0.1)) # Release the left mouse button to drop the piece mouse.release(Button.left) # Wait a moment before closing the browser to ensure the action completes sleep(5) driver.quit() # Close the browser session
Підсумок
Не знаю, як ви, але я отримав велике задоволення від цього проєкту. Завжди захопливо бачити, як комп’ютерний зір та автоматизація можуть об’єднуватися для розв’язання реальних проблем, як-то обхід CAPTCHA! І цікаво, який наступний вигляд матиме капча 🤔
3 коментарі
Додати коментар Підписатись на коментаріВідписатись від коментарів