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

от автора

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

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

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

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

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

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

  • Подстановка прокси

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Решение первой капчи на 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("some_post43120@gmail.com")     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шники собираются у костра этой байкой пугают джунов.

В общем – скрипт Фанкапчу не решает, но готов к конструктиву и предложениям, как сделать так, чтобы начал решать.

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

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


ссылка на оригинал статьи https://habr.com/ru/articles/853018/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *