По роду деятельности я не разработчик, но вращаюсь в этих кругах, так скажем – околоPYTHONная тусовка. Есть знакомые разработчики и даже больше – коллеги.
Как это часто бывает, понадобилось мне организовать решение капчи на Python для одного важного проекта – парсер под Амазон. Было перепробована куча вариантов, израсходована не одна тонна промтов для чата GPT, но никак не поддавалась эта долбанная Амазон капча. В итоге – коллективным разумом (ну как коллективным, просьба была моя, а решение коллеги) был составлен скрипт для обхода капчи на 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 ты это делаешь или на другом языке.
Открытие страницы регистрации на Амазон
Далее скрипт открывает страницу регистрации на Амазон (за это отвечает эта функция — 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/
Добавить комментарий