Треть из 100 000 крупнейших сайтов используют CAPTCHA для защиты от ботов, поэтому, вероятно, капча когда-либо мешала вам при попытке спарсить данные.
Такая защита создана, чтобы пропускать людей и задерживать ботов. Но значит ли это, что ее невозможно обойти? К счастью, можно! В этой статье вы узнаете о трех различных способах обхода капчи через Selenium на Python:
- Решатель CAPTCHA.
- Плагин для имитации человеческой активности.
- Улучшение маскировки ваших запросов.
Давайте же их рассмотрим!?
Смотрите также: “Selenium с Python для нахождения XPath определенных объектов”.
Скачать одну из самых популярных книг по тестированию "Как тестируют в Google"
Может ли Selenium обойти CAPTCHA?
Капча обычно появляется, когда посетитель сайта ведет себя подозрительно, напоминая действия ботов, например просмотр множества страниц без прокрутки. Но Selenium и тут может помочь.
Существует два основных метода обхода заданий от капчи: вы можете решать их, заплатив людям (дорого в масштабе, но иногда полезно), либо предотвращать их появление, применяя передовые методы (и повторять запрос в случае неудачи). Selenium поможет вам взаимодействовать с формой в первом случае и сделать ваш трафик более похожим на человеческий во втором.
Способ 1. Обход CAPTCHA с помощью Selenium и 2Captcha
Допустим, вам нужно решить капчу, например, чтобы отправить форму. Для этого мы воспользуемся популярным сервисом по решению капчи 2captcha, в Selenium с на примере демо-страницы.
Мы рассмотрим, как этот сервис справляется с популярной задачей в CAPTCHA. Итак, для начала установим несколько зависимостей. Если у вас их еще нет, выполните команду pip install selenium 2captcha-python
и импортируйте необходимые модули, как показано ниже.
Примечание. Раньше установка WebDriver была обязательным шагом, но теперь уже нет. Selenium версии 4 и выше поставляется со встроенным WebDriver по умолчанию. Если у вас более старая версия Selenium, рекомендуется обновить ее, чтобы получить доступ к новейшим функциям и возможностям. Вы можете проверить текущую версию с помощью команды pip show selenium
и обновить ее до последней версии с помощью pip install --upgrade selenium
.
from selenium.webdriver.common.by import By from twocaptcha import TwoCaptcha from selenium import webdriver import time
Затем откройте экземпляр Chrome и перейдите на демо-страницу.
driver = webdriver.Chrome() url = "https://2captcha.com/demo/normal" driver.get(url)
Следующим шагом будет нахождение изображения капчи и передача его URL в метод solver.normal()
, который возвращает решение текстом. Сохраните его в переменной result
.
imgResults = driver.find_elements(By.XPATH,"//img[contains(@class,'_2hXzbgz7SSP0DXCyvKWcha')]") solver = TwoCaptcha(Your_2Captcha_API_key) result=solver.normal(imgResults[0].get_attribute('src')) print ('solved: ' + str(result))
Следующая задача – найти поле ввода, вставить в него текст решения, полученный от сервиса 2Captcha, и нажать кнопку отправки.
captchafield = driver.find_element(By.XPATH,"//input[contains(@class,'_26Pq0m_qFk19UXx1w0U5Kv')]") captchafield.send_keys(result['code']) button = driver.find_element(By.XPATH,"//button[contains(@class, 'l2z7-tVRGe-3sq5kU4uu5 _2xjDiWmBxfqem8nGQMmGci _2HIb5VBFp6Oi5_JoLdEcl6 _2vbG_IBm-DpI5KeEAHJkRy')]") button.click() time.sleep(10)
Для завершения найдите на странице элемент <p>
и выведите его сообщение. В случае успеха вы должны получить сообщение ”Captcha is passed successfully!’.
messagefield=driver.find_element(By.XPATH,"//p[contains(@class,'_2WOJoV7Dg493S8DW_GobSK')]") print (messagefield.text)
Вот полный код:
from selenium.webdriver.common.by import By from twocaptcha import TwoCaptcha from selenium import webdriver import time driver = webdriver.Chrome() url = "https://2captcha.com/demo/normal" driver.get(url) imgResults = driver.find_elements(By.XPATH,"//img[contains(@class,'_2hXzbgz7SSP0DXCyvKWcha')]") solver = TwoCaptcha(Your_2Captcha_API_key) result = solver.normal(imgResults[0].get_attribute("src")) print ("solved: " + str(result)) captchafield = driver.find_element(By.XPATH,"//input[contains(@class,'_26Pq0m_qFk19UXx1w0U5Kv')]") captchafield.send_keys(result["code"]) button = driver.find_element(By.XPATH,"//button[contains(@class, 'l2z7-tVRGe-3sq5kU4uu5 _2xjDiWmBxfqem8nGQMmGci _2HIb5VBFp6Oi5_JoLdEcl6 _2vbG_IBm-DpI5KeEAHJkRy')]") button.click() time.sleep(10) messagefield=driver.find_element(By.XPATH,"//p[contains(@class,'_2WOJoV7Dg493S8DW_GobSK')]") print (messagefield.text)
И вот результат его выполнения:
solved: {'captchaId': '72848141048', 'code': 'W9H5K'} Captcha is passed successfully!
Поздравляем! Вы решили свою первую капчу с помощью Selenium и 2Captcha.
Однако использование платных решений трудно масштабировать, поскольку это будет дорого и медленно, и они работают не со всеми типами капчи. Поэтому давайте рассмотрим также альтернативный вариант.
Способ 2. Внедрение Selenium Stealth
Работу Selenium легко выявить, поскольку его базовая версия отправляет несколько явных сигналов бота, например, имя User-Agent, что легко может вызвать появление капчи. И чтобы продемонстрировать это, давайте попробуем получить доступ к защищенному сайту OpenSea.
Создайте экземпляр Chrome в headless-режиме, передайте URL в функцию get()
, чтобы дождаться загрузки страницы, и сделайте скриншот.
from selenium import webdriver from selenium.webdriver.chrome.options import Options import time options = Options() options.add_argument("--headless") driver = webdriver.Chrome(options=options) driver.get("https://opensea.io/") time.sleep(30) driver.save_screenshot("opensea.png") driver.close()
Какой будет результат?
Доступ закрыт! OpenSea обнаружил нечеловеческий трафик и заблокировал нашего бота. В таком случае на помощь нам придет библиотека для Python – selenium-stealth. Она позволит сделать наш трафик более человечным, что предотвратит блокировку от CAPTCHA.
Для начала установите пакет Stealth: pip install selenium-stealth
.
Затем импортируйте несколько необходимых библиотек и настройте драйвер для запуска Chrome в режиме headless. Далее исключите enable-automation
и отключите useAutomationExtension
, поскольку сайты выявляют трафик ботов при наличии этих флагов.
from selenium import webdriver from selenium.webdriver.chrome.options import Options import time from selenium_stealth import stealth options = Options() options.add_argument("--headless") options.add_experimental_option("excludeSwitches", ["enable-automation"]) options.add_experimental_option("useAutomationExtension", False)
На следующем шаге создается экземпляр ChromeDriver с пользовательскими параметрами:
driver = webdriver.Chrome(options=options)
Теперь давайте воспользуемся функцией stealth()
для установки пользовательских конфигураций Chrome webdriver, чтобы сделать нашего бота менее обнаружаемым. Например, мы установим user-agent, который будет передаваться в HTTP-запросе.
stealth(driver, user_agent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.5481.105 Safari/537.36', languages=["en-US", "en"], vendor="Google Inc.", platform="Win32", webgl_vendor="Intel Inc.", renderer="Intel Iris OpenGL Engine", fix_hairline=True, )
Затем скрипт переходит на нашу страницу, дожидается ее загрузки и делает скриншот:
driver.get("https://opensea.io/") time.sleep(30) driver.save_screenshot("opensea.png") driver.close()
Код целиком:
from selenium import webdriver from selenium.webdriver.chrome.options import Options import time from selenium_stealth import stealth options = Options() options.add_argument("--headless") options.add_experimental_option("excludeSwitches", ["enable-automation"]) options.add_experimental_option("useAutomationExtension", False) driver = webdriver.Chrome(options=options) stealth(driver, user_agent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.5481.105 Safari/537.36', languages=["en-US", "en"], vendor="Google Inc.", platform="Win32", webgl_vendor="Intel Inc.", renderer="Intel Iris OpenGL Engine", fix_hairline=True, ) driver.get("https://opensea.io/") time.sleep(30) driver.save_screenshot("opensea2.png") driver.close()
Давайте теперь проверим результат:
Успех! Мы смогли успешно обойти CAPTCHA с помощью Selenium.
Однако будет ли selenium-stealth работать, парся сайты с самой высокой защитой от ботов? Попробуйте зайти на страницу обзора на G2, и вы получите ответ.
Если для ваших целей не подошли первые 2 способа, следует поискать лучший вариант.
Способ 3. Обход CAPTCHA с помощью API ZenRows
Для парсинга контента с сайтов с продвинутой защитой необходим правильный инструмент. ZenRows – это мощный анти-бот API, предоставляющий вам функциональность headless-браузера, через который можно проводить масштабный парсинг данных, обходя средства защиты от ботов, в том числе и CAPTCHA.
Давайте посмотрим, как легко собрать контент из G2 с помощью ZenRows.
Во-первых, зарегистрируйтесь для получения бесплатного API ключа. Вы попадете в конструктор запросов, где нужно ввести <https://www.g2.com/products/asana/reviews>
в качестве целевого URL, а затем активировать Premium Proxy
, JavaScript Rendering
и Antibot
.
Во-вторых, скопируйте и вставьте запрос к API в вашу Python IDE. Он должен выглядеть следующим образом:
# python3 and requests library required # pip install requests import requests response = requests.get("https://api.zenrows.com/v1/?apikey=Your_ZenRows_API_Key&url=https%3A%2F%2Fwww.g2.com%2Fproducts%2Fasana%2Freviews%2F&js_render=true&antibot=true&premium_proxy=true") print(response.text)
В-третьих, запустите код и посмотрите, как он выводит HTML с сайта G2.
Заключение
Мы увидели, как можно обойти CAPTCHA с помощью Selenium, используя платный решатель, но выяснили, что в качестве самостоятельного решения такой способ может быть ненадежным и затратным. Затем мы установили плагин для базового Selenium, который мог бы помочь в масштабном сборе данных, однако его эффективности оказалось недостаточно.
Для успешного парсинга данных вам нужен мощный инструмент, на который можно полностью полагаться, чтобы всегда обходить капчу. ZenRows предоставляет простой в настройке API, способный обходить все средства защиты от ботов.
Перевод статьи «How to Bypass CAPTCHA with Selenium».