Обход капчи Python, что сложного? Но есть определенные нюансы

По роду деятельности я не разработчик, но вращаюсь в этих кругах, так скажем – околоPYTHONная тусовка. Есть знакомые разработчики и даже больше – коллеги.

Обход капчи Python, что сложного? Но есть определенные нюансы

Как это часто бывает, понадобилось мне организовать решение капчи на Python для одного важного проекта – парсер под Амазон. Было перепробована куча вариантов, израсходована не одна тонна промтов для чата GPT, но никак не поддавалась эта долбанная Амазон капча. В итоге – коллективным разумом (ну как коллективным, просьба была моя, а решение коллеги) был составлен скрипт для обхода капчи на Python, и решение выложить его в общий доступ продиктовано исключительно благими намерениями корыстными побуждениями. Нужны советы, по оптимизации работы этого скрипта, потому что мы с чатом уже все, сдулись. Перепробовали несколько подходов, сломали кучу библиотек, но стабильной работы скрипта в итоге не получили.

Обход капчи Python, что сложного? Но есть определенные нюансы

Давайте по порядку:

Общее описание скрипта для обхода капчи на Python

Скрипт обхода капчи на Python работает по такому принципу:

  • Импортирует необходимые для работы библиотеки
  • Подстановка прокси

  • Открывает страницу регистрации на Амазон

  • Решение первой капчи (если ее нет – пропуск)

  • Заполнение формы регистрации

  • Решение второй капчи координатным методом

  • Проверка решения капчи

  • Закрытие браузера

Теперь разберемся с каждым пунктом отдельно.

Необходимые для решения капчи Python библиотеки

Скрипт использует несколько библиотек:

  • os, base64, BytesIO - стандартные библиотеки Python, которые используются для работы с файловой системой, кодирования изображений в base64 и работы с потоками байтов (можно сказать, что этот набор библиотек используется для обхода капчи в виде изображения).

  • seleniumbase.Driver, selenium.webdriver.common.by.By, selenium.webdriver.common.action_chains.ActionChains - Эти библиотеки позволяют управлять браузером через Selenium, выполнять поиск элементов на веб-странице и выполнять сложные действия с ними (например, клик по координатам) (таким образом, этот набор библиотек большей степенью предназначен для решения капчи координатным методом, но не стоит забывать, что в принципе все взаимодействие с капчей зависит в данном скрипте от Селениума, так что это самый важный набор библиотек).

  • TwoCaptcha: Библиотека для работы с сервисом 2Captcha для автоматического распознавания капчи (естественно, решение капчи Python реализовано через сторонний сервис, в нашем случае сервис 2капча).

Подстановка прокси для функционирования скрипта

Изначально скрипт был настроен таким образом, чтобы прокси брались из файла, но так как я достаточно ленивый (Что? Создать файл для прокси, разобраться в каком формате записывать туда прокси, подготовить эти прокси в нужном формате, да вы издеваетесь?), пришлось добавить возможность использования прокси прямо из кода.

То есть, скрипт сперва проверяет, есть ли файл с прокси и если его нет – подгружает прокси из кода. А если и там нет прокси, то скрипт просто забивает на работу и отключается (прям как некоторые работники – «я человек простой, не поставили задачу – просто листаю видосики»)

Обход капчи Python, что сложного? Но есть определенные нюансы

В принципе обход капчи без прокси в современном мире уже признак дурного тона (особенно если поток огромный), и неважно на Python ты это делаешь или на другом языке.

Обход капчи Python, что сложного? Но есть определенные нюансы

Открытие страницы регистрации на Амазон

Далее скрипт открывает страницу регистрации на Амазон (за это отвечает эта функция - driver.uc_open_with_reconnect:). Конечная цель ведь у скрипта – регистрация на сайте, а не распознавание капчи (хотя больше он пока что ничего сделать и не может, если быть до конца честным.

Обход капчи Python, что сложного? Но есть определенные нюансы

Решение первой капчи на Python

Вот мы наконец-то и добрались до ключевой функции (вернее ее части) - обход капчи либо пропуск, если капчи нет. Речь про простую текстовую Амазон капчу, она то появляется то нет (все зависит от того, какие дни у Амазон).

Работает это так – скрипт при помощи selenium находит изображение капчи на странице и делает его скриншот, после чего преобразует скрин в формат base64 и отправляет получившийся набор букв и символов на сервис 2капча для обхода, а после получения ответа от сервера подставляет текст в специальное поле и жмет кнопку «Продолжить».

Соответственно, если обходить нечего (капча не появилась) этот пункт просто пропускается и скрипт переходит к следующему.

Заполнение формы регистрации

Как вы помните, перед тем, как попытаться решить капчу скрипт открыл страницу регистрации, собственно к ней он и возвращается и заполняет регистрационную форму.

Данные для регистрационной формы загружаются прямиком из кода, и это сделано как раз по той причине, что необходимо до конца допилить модуль распознавания капчи.

В идеале, сюда можно дописать свое решение, которое будет брать данные для заполнения формы из файла методом перебора и таким образом в автоматическом режиме можно заполнять много форм.

Обход капчи Python координатным методом

С первой капчей, за все время тестирования этого модуля у меня ни разу не возникло никаких заморочек (ну тупо Амазон был в хорошем расположении духа и ни разу не выдал мне текстовую капчу), а вот со второй появились вопросики, как к скрипту, так и к комьюнити.

Давайте разберемся:

Итак, вторая капча более сложная и требует указания куда нужно кликнуть, чтобы ее обойти. Принцип работы скрипта такой – делается скриншот и отправляется на сервис для получения координат.

Сервис присылает координаты и скрипт, используя ActionChains перемещает курсор на указанные координаты, после чего переключается во фрейм и нажимает кнопку подтверждения.

И вот дальше происходит то самое волшебство тот самый затык. Либо в момент распознавания, либо на шаге проверки иногда происходит провис, то есть капча либо не решается, либо заканчивается время на решение капчи и она обновляется, не успев получить правильный результат. В большинстве случаев все решается, но вот это исключение из большинства случаев мне и не дает покоя…

Ниже приведу сам скрипт, может кому то будет полезным, а может кто-то в комментах даст рекомендацию, что по его мнению можно доработать, чтобы пофиксить этот момент?

Либо, это не исправить, так как ответ такой – «Это же Амазон»…

import os import base64 from io import BytesIO from seleniumbase import Driver from selenium.webdriver.common.by import By from selenium.webdriver.common.action_chains import ActionChains from twocaptcha import TwoCaptcha # pip3 install 2captcha-python # Прокси для ручного ввода manual_proxy = "http://login:password@ip:port" # Замените на ваш прокси # Функция для чтения прокси из файла def get_proxy_from_file(file_path): if os.path.exists(file_path): with open(file_path, 'r') as file: proxy = file.read().strip() return proxy return None # Попробуем сначала подключить прокси из внешнего файла, если файл отсутствует, используем ручное значение proxy_file_path = "proxy.txt" # Имя файла с прокси proxy = get_proxy_from_file(proxy_file_path) or manual_proxy my_key = "API Key 2captcha" solver = TwoCaptcha(my_key, defaultTimeout=70) agent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36" # Инициализация драйвера с прокси driver = Driver(uc=True, headless=False, proxy=proxy, agent=agent) # headless=True for invisible mode try: url = "https://www.amazon.com/ap/register?openid.pape.max_auth_age=0&openid.identity=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0%2Fidentifier_select&pageId=usflex&ignoreAuthState=1&openid.assoc_handle=usflex&openid.mode=checkid_setup&openid.ns.pape=http%3A%2F%2Fspecs.openid.net%2Fextensions%2Fpape%2F1.0&prepopulatedLoginId=&failedSignInCount=0&openid.claimed_id=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0%2Fidentifier_select&disableLoginPrepopulate=1&switch_account=signin&openid.ns=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0" driver.uc_open_with_reconnect(url, 5) # Решение первой капчи try: my_img = driver.find_element("body > div > div.a-row.a-spacing-double-large > div.a-section > div > div > form > div.a-row.a-spacing-large > div > div > div.a-row.a-text-center > img") print("SOLVE FIRST CAPTCHA...") screenshot = my_img.screenshot_as_png screenshot_bytes = BytesIO(screenshot) base64_screenshot = base64.b64encode(screenshot_bytes.getvalue()).decode('utf-8') result = solver.normal(base64_screenshot) print('result: ' + str(result)) # Отправка запроса на сервис 2Captcha res = result['code'] driver.find_element(By.ID, "captchacharacters").send_keys(f"{res}") driver.find_element(By.CLASS_NAME, "a-button-inner").click() except: pass # Ожидание и заполнение формы driver.sleep(1) print("Fill out the form") driver.find_element(By.ID, "ap_customer_name").send_keys("Alex0053") # Заполнение формы driver.find_element(By.ID, "ap_email").send_keys("[email protected]") driver.find_element(By.ID, "ap_password").send_keys("password40000A#") driver.find_element(By.ID, "ap_password_check").send_keys("password40000A#") driver.find_element(By.ID, "continue").click() driver.sleep(10) # Вторая капча - координатная while True: try: cap_img = driver.find_element(By.ID, "cvf-aamation-challenge-iframe") # Доработка элемента фрейма print("SOLVE SECOND-COORD CAPTCHA...") screenshot = cap_img.screenshot_as_png screenshot_bytes = BytesIO(screenshot) base64_screenshot = base64.b64encode(screenshot_bytes.getvalue()).decode('utf-8') element_position = cap_img.location result = solver.coordinates(base64_screenshot, lang='en', min_clicks=1, max_clicks=1) x = str(result['code']).split(":")[1].split(",")[0].replace("x=", "") y = str(result['code']).split(":")[1].split(",")[1].replace("y=", "") print('result: ' + str(result)) x_coord = element_position["x"] + int(x) y_coord = element_position["y"] + int(y) actions = ActionChains(driver) actions.move_by_offset(x_coord, y_coord).click().perform() driver.sleep(2) actions.reset_actions() driver.switch_to_frame(cap_img) driver.find_element(By.ID, "amzn-btn-verify-internal").click() driver.switch_to.default_content() driver.sleep(7) except Exception as e: print(e) try: driver.find_element('form[id="verification-code-form"]') print("CAPTCHA PASSED!!!") break except: pass driver.sleep(3) # Последний блок кода, если нужно except Exception as e: print(e) finally: driver.close() driver.quit()

Обход капчи Python – раздел которого в коде нет

У Амазон еще есть третий вид капчи, Фанкапча, и я не смог победить ее в данном контексте, поэтому просто выпилил из этого кода на всякий случай. Да и Фанкапча за все время тестирования мне так ни разу не встретилась (но из разговоров мудрейших я знаю что она там есть, где то в чертогах Амазона). Ходят легенды, что есть специально обученный мужик, назовем его просто СОМ, который руками меняет условия для обхода капчи, либо дизайн страницы.

Никто этого СОМа никогда не видел, но у вечерами, когда ITшники собираются у костра этой байкой пугают джунов.

Обход капчи Python, что сложного? Но есть определенные нюансы

В общем – скрипт Фанкапчу не решает, но готов к конструктиву и предложениям, как сделать так, чтобы начал решать. Итого вывод: Скрипт работает, обход капчи осуществляется, но встречаются провисы – было бы неплохо, если бы на них указали (желательно без минусения)

Скрипт не решает Фанкапчу, но на первый взгляд и не нужОна нам эта ваш фанкапча, но если нужна – также, буду рад почитать мнение коммьюнити.

2 комментария

Если капча обходится скриптом, то это плохая капча.

Ответить

Ну, в этой ситуации, как бы эт самое, наши полномочия все... Окончены

Ответить