Selenium – одна из самых известных и широко используемых библиотек для автоматизации тестирования веб-приложений. Она появилась в 2004 году, когда Джейсон Хаггинс, работая в ThoughtWorks, решил создать инструмент для автоматизированного тестирования своих веб-приложений. Джейсон заметил, что ручное тестирование стало слишком трудоемким и требовало много времени, поэтому он разработал JavaScript-библиотеку, которая могла управлять браузером автоматически. Этот инструмент получил название Selenium.
Первоначально Selenium был создан для выполнения тестов в веб-браузере через JavaScript, что делало его мощным средством для кросс-браузерного тестирования. Со временем проект рос и развивался, добавляя поддержку новых языков программирования и платформ. На сегодняшний день Selenium поддерживает такие языки, как Java, Python, C#, Ruby, JavaScript и Kotlin, что делает его универсальным инструментом для разработчиков и тестировщиков по всему миру.
Selenium включает в себя несколько компонентов, среди которых наиболее известны Selenium IDE и Selenium WebDriver. Selenium IDE (Integrated Development Environment) – это инструмент для записи и воспроизведения тестов. Он работает как расширение для браузеров Firefox и Chrome, позволяя пользователям записывать свои действия и автоматически генерировать тестовые скрипты. Это особенно полезно для новичков, так как не требует глубоких знаний в программировании.
Selenium WebDriver, с другой стороны, – это более продвинутая и гибкая часть Selenium. WebDriver предоставляет программный интерфейс для управления веб-браузерами. В отличие от Selenium IDE, WebDriver позволяет писать тесты на различных языках программирования и поддерживает более сложные сценарии тестирования. Он работает напрямую с браузерами, используя их родные API, что делает его более быстрым и надежным инструментом для автоматизации.
Для использования Selenium WebDriver необходимо иметь установленные драйвера, соответствующие браузеру, с которым вы работаете. Изначально пользователи должны были самостоятельно скачивать и устанавливать эти драйвера с официальных сайтов браузеров. Это добавляло дополнительную сложность, так как требовалось следить за совместимостью версий драйвера и браузера.
С течением времени появилась сторонняя библиотека для управления драйверами, что значительно упростило процесс. Но настоящим прорывом стало внедрение менеджера драйверов непосредственно в библиотеку Selenium. Теперь Selenium автоматически загружает и устанавливает нужные драйвера в зависимости от версии браузера, установленного в системе, что делает процесс настройки и использования Selenium гораздо проще и удобнее.
Selenium великолепно подходит для тестирования веб-приложений. Он позволяет автоматизировать выполнение различных сценариев, таких как проверка логики работы приложения, проверка пользовательского интерфейса, тестирование функциональности различных элементов сайта. Тестировщики и автоматизаторы пишут тесты с помощью Selenium WebDriver на таких языках, как Python, Java и других, что делает процесс тестирования быстрым и эффективным.
Кроме того, Selenium часто используется для сбора данных с веб-сайтов (веб-скрапинг). Благодаря своей способности взаимодействовать с элементами страницы, Selenium идеально подходит для работы с сайтами, где требуется авторизация или присутствует динамическая подгрузка контента. Это делает его незаменимым инструментом для разработчиков и исследователей, которым необходимо извлекать данные с веб-страниц.
Эта статья охватила лишь начальные аспекты Selenium, предоставив обзор его истории, ключевых компонентов и применения. В следующих частях мы углубимся в конкретные примеры использования и дополнительные возможности этой мощной библиотеки.
Для начала работы с Selenium в Python необходимо установить саму библиотеку. Это делается очень просто с помощью менеджера пакетов pip. Откройте командную строку (или терминал) и выполните следующую команду:
pip install selenium
Эта команда скачает и установит последнюю версию библиотеки Selenium, которая на момент написания этой статьи является версией 4.0. Убедитесь, что у вас установлена последняя версия Python и pip, чтобы избежать возможных проблем совместимости.
После установки Selenium можно приступать к созданию скриптов для автоматизации работы с веб-браузером. Первым шагом будет создание экземпляра веб-драйвера. В данном примере мы будем использовать браузер Chrome, но аналогично можно работать и с другими браузерами.
Selenium WebDriver позволяет программно управлять браузером. При первом запуске скрипта Selenium автоматически скачает нужный драйвер для вашего браузера. Важно, чтобы сам браузер был установлен в системе. Например, если вы используете Chrome, убедитесь, что он установлен на вашем компьютере.
Ниже приведен пример кода для создания экземпляра веб-драйвера:
from selenium import webdriver
# Создаем экземпляр веб-драйвера для браузера Chrome
driver = webdriver.Chrome()
# Открываем веб-страницу
driver.get('https://www.example.com')
# Закрываем браузер
driver.quit()
-
Импорт библиотеки: В первой строке мы импортируем модуль webdriver из библиотеки selenium. Это необходимо для того, чтобы использовать возможности Selenium WebDriver.
-
Создание экземпляра веб-драйвера: В следующей строке мы создаем экземпляр веб-драйвера для браузера Chrome с помощью
webdriver.Chrome()
. Этот вызов автоматически скачает и установит нужный драйвер, если он еще не был скачан ранее. Это возможно благодаря встроенному менеджеру драйверов в Selenium 4. Если браузер Chrome установлен на вашем компьютере, Selenium найдет его и настроит драйвер. -
Открытие веб-страницы: Метод
get
используется для открытия указанного URL. В данном примере мы открываем страницу 'https://www.example.com'. -
Закрытие браузера: Метод
quit
закрывает браузер и завершает работу веб-драйвера. Это важно для освобождения ресурсов и предотвращения утечек памяти.
-
Первый запуск: Первый запуск вашего скрипта может занять немного больше времени, так как Selenium будет скачивать и устанавливать нужный драйвер для вашего браузера. Это однократный процесс, и последующие запуски будут происходить быстрее.
-
Установленный браузер: Убедитесь, что браузер, с которым вы собираетесь работать, установлен на вашем компьютере. Selenium автоматически найдет его и настроит соответствующий драйвер.
Этот простой пример демонстрирует, как начать работу с Selenium в Python, создавая экземпляр веб-драйвера и управляя браузером. В следующих частях мы рассмотрим более сложные сценарии и возможности этой мощной библиотеки.
Работа с Selenium WebDriver включает множество полезных команд, позволяющих управлять браузером и взаимодействовать с веб-страницами. В этой статье мы рассмотрим основные команды, которые помогут вам начать автоматизировать задачи.
Метод get
используется для открытия веб-страницы. Эта команда отправляет запрос к указанному URL и загружает страницу в браузер. Рассмотрим пример:
from selenium import webdriver
driver = webdriver.Chrome()
driver.get('http://books.toscrape.com/')
В этом примере мы открываем сайт Books to Scrape, учебный сайт для парсинга.
Метод back
позволяет вернуться на предыдущую страницу, аналогично нажатию кнопки "Назад" в браузере. Это удобно для навигации между страницами без необходимости повторного ввода URL. Пример использования:
driver.get('http://books.toscrape.com/catalogue/category/books/fiction_10/index.html')
driver.back()
В этом примере сначала открывается страница категории книг "Fiction", затем мы возвращаемся на главную страницу сайта.
Selenium позволяет делать скриншоты текущей страницы с помощью метода save_screenshot
. Это полезно для сохранения визуального состояния страницы в определенный момент времени. Пример создания скриншота:
driver.get('http://books.toscrape.com/')
driver.save_screenshot('homepage.png')
Этот код откроет главную страницу сайта и сохранит ее скриншот в файл homepage.png
.
Команда | Описание | Пример |
---|---|---|
get(url) |
Открывает веб-страницу по указанному URL | driver.get('http://books.toscrape.com/') |
back() |
Возвращает на предыдущую страницу | driver.back() |
save_screenshot(path) |
Создает скриншот текущей страницы и сохраняет его в файл | driver.save_screenshot('homepage.png') |
-
Метод GET: Эта команда используется для загрузки веб-страницы по указанному URL. Она является одной из самых базовых и часто используемых команд в Selenium. Метод
get
ожидает завершения загрузки страницы, прежде чем передать управление следующей строке кода. -
Метод back: Позволяет вернуться на предыдущую страницу в истории браузера. Это полезно при автоматизации сценариев, где нужно проверить взаимодействие с несколькими страницами последовательно и затем вернуться к исходной странице.
-
Метод save_screenshot: Делает скриншот текущей страницы и сохраняет его в указанный файл. Этот метод полезен для отладки и документирования тестов, позволяя видеть, как выглядела страница в момент выполнения теста.
Мы рассмотрели основные команды, которые можно использовать с Selenium WebDriver для навигации по веб-страницам и создания скриншотов. Эти команды помогут вам начать автоматизировать ваши тесты и взаимодействие с веб-сайтами. В следующих частях мы углубимся в более сложные команды и возможности Selenium WebDriver.
В веб-автоматизации с использованием Selenium важно уметь находить и взаимодействовать с элементами на веб-странице. Ранее для поиска элементов использовались методы типа findElementById
, findElementByName
, findElementsByClassName
и другие. Эти методы всё ещё работают, но считаются устаревшими и могут быть удалены в будущих версиях Selenium.
Вместо них теперь рекомендуется использовать методы с объектом By
, который предлагает более современный и удобный способ поиска элементов. Для использования By
, его необходимо импортировать из модуля selenium.webdriver.common.by
. Давайте рассмотрим, как это работает.
Прежде всего, необходимо импортировать объект By
:
from selenium import webdriver
from selenium.webdriver.common.by import By
Методы findElement
и findElements
используют объект By
для поиска элементов на странице. Вот как это выглядит:
driver.find_element(By.ID, 'element_id')
driver.find_elements(By.CLASS_NAME, 'class_name')
Рассмотрим несколько примеров с сайта Books to Scrape:
- Поиск элемента по тегу:
element = driver.find_element(By.TAG_NAME, 'h1')
Этот код находит первый элемент с тегом <h1>
на странице.
- Поиск элемента по имени класса:
elements = driver.find_elements(By.CLASS_NAME, 'product_pod')
Этот код находит все элементы с классом product_pod
.
- Поиск элемента по CSS-селектору:
element = driver.find_element(By.CSS_SELECTOR, '.product_pod h3 a')
Этот код находит первый элемент <a>
внутри <h3>
, который, в свою очередь, находится внутри элемента с классом product_pod
.
Объект By
предоставляет различные методы для поиска элементов. Вот сводная таблица этих методов:
Метод | Синтаксис | Описание |
---|---|---|
By.ID |
By.ID, 'id' |
Поиск элемента по его уникальному идентификатору (id). |
By.NAME |
By.NAME, 'name' |
Поиск элемента по атрибуту name . |
By.CLASS_NAME |
By.CLASS_NAME, 'class_name' |
Поиск элемента по имени класса. |
By.TAG_NAME |
By.TAG_NAME, 'tag_name' |
Поиск элемента по тегу (например, h1 , div ). |
By.CSS_SELECTOR |
By.CSS_SELECTOR, 'css_selector' |
Поиск элемента с использованием CSS-селектора. |
By.XPATH |
By.XPATH, 'xpath' |
Поиск элемента с использованием XPath. |
By.LINK_TEXT |
By.LINK_TEXT, 'link_text' |
Поиск ссылки (<a> ) по тексту, содержащемуся в ней. |
By.PARTIAL_LINK_TEXT |
By.PARTIAL_LINK_TEXT, 'partial_link_text' |
Поиск ссылки (<a> ) по частичному тексту, содержащемуся в ней. |
- By.ID: Поиск элемента по его уникальному идентификатору. Уникальный идентификатор — это значение атрибута
id
элемента HTML. - By.NAME: Поиск элемента по атрибуту
name
, который часто используется в формах. - By.CLASS_NAME: Поиск элемента по имени класса. Удобен для поиска элементов, которые разделяют общий класс CSS.
- By.TAG_NAME: Поиск элемента по тегу, такому как
div
,span
,h1
и т.д. - By.CSS_SELECTOR: Поиск элемента с использованием CSS-селектора. Это мощный способ, позволяющий использовать селекторы классов, идентификаторов и другие возможности CSS.
- By.XPATH: Поиск элемента с использованием XPath. XPath предоставляет мощные возможности для навигации по структуре XML и HTML-документов.
- By.LINK_TEXT: Поиск ссылки (
<a>
) по полному тексту, содержащемуся в ней. - By.PARTIAL_LINK_TEXT: Поиск ссылки (
<a>
) по частичному тексту, содержащемуся в ней.
Эти методы позволяют гибко и точно находить элементы на веб-страницах, что делает Selenium мощным инструментом для автоматизации веб-тестирования и других задач, связанных с веб-разработкой.
Работа с элементами на веб-странице – ключевой аспект автоматизации с Selenium WebDriver. Мы рассмотрим, как использовать различные методы поиска элементов на примере сайта Books to Scrape.
Метод By.ID
позволяет найти элемент по его уникальному идентификатору. Например, если у нас есть элемент с id="search"
, мы можем найти его следующим образом:
element = driver.find_element(By.ID, 'search')
Метод By.NAME
ищет элементы по атрибуту name
. Это полезно при работе с формами:
element = driver.find_element(By.NAME, 'search')
Метод By.CLASS_NAME
используется для поиска элементов по имени класса. Важно отметить, что он принимает только одно имя класса, но если элемент имеет несколько классов, вы можете использовать любой из них для поиска:
elements = driver.find_elements(By.CLASS_NAME, 'product_pod')
Этот код найдет все элементы с классом product_pod
на странице.
Метод By.TAG_NAME
ищет элементы по их тегу. Например, чтобы найти все заголовки <h3>
на странице:
elements = driver.find_elements(By.TAG_NAME, 'h3')
Метод By.CSS_SELECTOR
является невероятно гибким и мощным, так как позволяет использовать все возможности CSS-селекторов для поиска элементов:
element = driver.find_element(By.CSS_SELECTOR, '.product_pod h3 a')
Этот код найдет первый элемент <a>
, находящийся внутри <h3>
, который, в свою очередь, находится внутри элемента с классом product_pod
.
Метод By.XPATH
позволяет находить элементы с использованием языка XPath, который предоставляет мощные возможности для навигации по структуре документа:
element = driver.find_element(By.XPATH, '//*[@id="default"]/div/div/div/div/section/div[2]/ol/li[1]/article/h3/a')
Хотя XPath предоставляет мощные возможности для точного поиска, он может быть ненадежным при изменениях в структуре страницы, особенно если страница активно изменяется с помощью JavaScript.
CSS-селекторы предлагают множество преимуществ:
- Гибкость: Позволяют использовать сложные правила для поиска элементов, включая вложенность и атрибуты.
- Скорость: Часто работают быстрее, чем XPath, особенно в современных браузерах.
- Простота: CSS-селекторы проще в написании и чтении по сравнению с XPath.
Пример поиска элемента по CSS-селектору:
element = driver.find_element(By.CSS_SELECTOR, '.nav a[href="catalogue/category/books_1/index.html"]')
Этот селектор найдет ссылку <a>
, которая находится внутри элемента с классом nav
и имеет атрибут href
, указывающий на страницу категории книг.
Метод | Синтаксис | Описание |
---|---|---|
By.ID |
By.ID, 'id' |
Поиск элемента по его уникальному идентификатору (id). |
By.NAME |
By.NAME, 'name' |
Поиск элемента по атрибуту name . |
By.CLASS_NAME |
By.CLASS_NAME, 'class_name' |
Поиск элемента по имени класса. Принимает только одно имя класса. |
By.TAG_NAME |
By.TAG_NAME, 'tag_name' |
Поиск элемента по тегу (например, h1 , div ). |
By.CSS_SELECTOR |
By.CSS_SELECTOR, 'css_selector' |
Поиск элемента с использованием CSS-селектора. |
By.XPATH |
By.XPATH, 'xpath' |
Поиск элемента с использованием XPath. |
By.LINK_TEXT |
By.LINK_TEXT, 'link_text' |
Поиск ссылки (<a> ) по тексту, содержащемуся в ней. |
By.PARTIAL_LINK_TEXT |
By.PARTIAL_LINK_TEXT, 'partial_link_text' |
Поиск ссылки (<a> ) по частичному тексту, содержащемуся в ней. |
- By.TAG_NAME:
elements = driver.find_elements(By.TAG_NAME, 'h3')
Находит все заголовки <h3>
на странице.
- By.CLASS_NAME:
elements = driver.find_elements(By.CLASS_NAME, 'product_pod')
Находит все элементы с классом product_pod
.
- By.CSS_SELECTOR:
element = driver.find_element(By.CSS_SELECTOR, '.product_pod h3 a')
Находит первый элемент <a>
внутри <h3>
, который находится внутри элемента с классом product_pod
.
Использование Selenium WebDriver с объектом By
предоставляет мощные и гибкие инструменты для поиска и взаимодействия с элементами на веб-страницах. Эти методы позволяют точно и эффективно автоматизировать задачи тестирования и парсинга.
Объект Options
в Selenium позволяет настраивать параметры запуска браузера для различных целей, таких как настройка разрешения экрана, запуск в режиме инкогнито или в режиме "без головы" (headless). Каждый браузер имеет свой собственный набор опций, которые можно найти в документации для конкретного браузера.
Для создания объекта Options
необходимо импортировать соответствующий класс для выбранного браузера. Например, для Chrome это будет ChromeOptions
.
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
options = Options()
- Запуск с конкретным разрешением экрана:
options.add_argument("window-size=1920,1080")
- Запуск в развернутом на весь экран режиме:
options.add_argument("--start-maximized")
- Запуск в режиме без головы (headless):
options.add_argument("--headless=new")
- Запуск в режиме инкогнито:
options.add_argument("--incognito")
При использовании нескольких опций важно учитывать, что некоторые из них могут быть несовместимы. Например, режим "без головы" (headless) будет работать с указанием разрешения экрана, но не будет работать с развертыванием на весь экран.
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
options = Options()
options.add_argument("window-size=1920,1080")
options.add_argument("--headless=new")
options.add_argument("--incognito")
driver = webdriver.Chrome(options=options)
driver.get("http://books.toscrape.com/")
driver.quit()
Режим "без головы" (headless) позволяет запускать браузер без отображения графического интерфейса, что ускоряет выполнение тестов и экономит ресурсы. Однако важно помнить, что Safari не поддерживает режим headless, в то время как другие браузеры, такие как Chrome и Firefox, поддерживают его. С версии 109 у Chrome появился улучшенный режим headless, который теперь рекомендуется использовать.
Опция | Описание | Пример использования |
---|---|---|
window-size=width,height |
Устанавливает размер окна браузера | options.add_argument("window-size=1920,1080") |
--start-maximized |
Запускает браузер в развернутом на весь экран режиме | options.add_argument("--start-maximized") |
--headless=new |
Запускает браузер в режиме "без головы" (новый режим) | options.add_argument("--headless=new") |
--incognito |
Запускает браузер в режиме инкогнито | options.add_argument("--incognito") |
Использование объекта Options
позволяет гибко настраивать параметры запуска браузера для различных сценариев тестирования. Эти настройки помогают создавать более стабильные и воспроизводимые тесты, учитывая особенности каждого браузера. При настройке опций важно внимательно читать документацию и учитывать совместимость различных параметров.
Объект WebElement
является результатом выполнения методов findElement
и findElements
. Он представляет собой элемент на веб-странице и предоставляет методы для взаимодействия с этим элементом, такие как click
, sendKeys
, getText
, и другие.
WebElement
можно многократно использовать для поиска внутри элемента. Это позволяет создавать цепочки поиска и взаимодействия с элементами.
Метод click
используется для симуляции клика мыши на элементе. Это полезно для взаимодействия с кнопками, ссылками и другими интерактивными элементами.
Пример использования метода click
:
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.options import Options
options = Options()
options.add_argument("--headless=new")
options.add_argument("window-size=1920,1080")
driver = webdriver.Chrome(options=options)
driver.get("http://books.toscrape.com/")
# Находим первую карточку товара и кликаем на заголовок
product_pod = driver.find_element(By.CLASS_NAME, 'product_pod')
product_pod.find_element(By.TAG_NAME, 'h3').find_element(By.TAG_NAME, 'a').click()
driver.quit()
Теперь рассмотрим более сложный пример, где мы будем искать все карточки товаров на странице, кликаем на заголовок каждого товара, переходим на страницу описания, делаем скриншот и возвращаемся назад.
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.options import Options
import time
options = Options()
options.add_argument("--headless=new")
options.add_argument("window-size=1920,1080")
driver = webdriver.Chrome(options=options)
driver.get("http://books.toscrape.com/")
# Находим все карточки товаров
product_pods = driver.find_elements(By.CLASS_NAME, 'product_pod')
for index, pod in enumerate(product_pods):
# Находим заголовок и кликаем на него
link = pod.find_element(By.TAG_NAME, 'h3').find_element(By.TAG_NAME, 'a')
link.click()
# Делаем скриншот страницы описания товара
driver.save_screenshot(f'product_{index}.png')
# Возвращаемся назад
driver.back()
# Ждем немного, чтобы страница успела загрузиться
time.sleep(1)
driver.quit()
- Импортируем необходимые модули: Импортируем
webdriver
,By
,Options
из библиотеки Selenium и модульtime
для задержек. - Создаем объект
Options
и задаем параметры: Включаем режим "без головы" и устанавливаем разрешение окна. - Создаем экземпляр веб-драйвера: Создаем объект
ChromeDriver
с заданными опциями и открываем сайт. - Находим все карточки товаров: Используем
findElements
для поиска всех элементов с классомproduct_pod
. - Перебираем карточки в цикле:
- Находим заголовок каждой карточки и кликаем на него.
- Делаем скриншот страницы описания товара.
- Возвращаемся назад и ждем, чтобы страница успела перезагрузиться.
Этот код демонстрирует, как можно использовать WebElement
для взаимодействия с элементами на веб-странице, включая многократное использование для поиска внутри элементов, выполнение кликов и другие действия.
При работе с Selenium могут возникать различные исключения (exceptions), указывающие на проблемы в процессе выполнения кода. Понимание этих исключений и умение их обрабатывать помогает сделать код более устойчивым и предсказуемым.
- NoSuchElementException: Возникает, когда Selenium не может найти элемент, соответствующий заданному селектору.
- ElementNotVisibleException: Происходит, когда элемент присутствует в DOM, но невидим и, следовательно, не может быть взаимодействованным.
- ElementNotInteractableException: Возникает, когда элемент доступен в DOM, но недоступен для взаимодействия.
- StaleElementReferenceException: Происходит, когда элемент, на который вы ссылаетесь, больше не присутствует на странице (например, после обновления страницы).
- TimeoutException: Возникает, когда ожидание элемента или условия истекает.
- WebDriverException: Общее исключение для ошибок, связанных с WebDriver.
Исключение | Описание | Когда происходит |
---|---|---|
NoSuchElementException |
Элемент не найден по заданному селектору | Элемент не существует в DOM или неправильный селектор |
ElementNotVisibleException |
Элемент не видим | Элемент скрыт CSS или находится за пределами видимой области |
ElementNotInteractableException |
Элемент не доступен для взаимодействия | Элемент доступен в DOM, но не доступен для клика или ввода текста |
StaleElementReferenceException |
Ссылка на элемент устарела | Элемент удален или изменен в DOM после его нахождения |
TimeoutException |
Время ожидания истекло | Ожидание элемента или условия не выполнено в установленное время |
WebDriverException |
Общее исключение для ошибок WebDriver | Произошла ошибка, связанная с WebDriver (например, проблемы с запуском драйвера) |
В Python для обработки исключений используются блоки try-except-else-finally
. Они позволяют ловить ошибки и реагировать на них, не прерывая выполнение программы.
- try: Блок, в котором выполняется код, потенциально вызывающий исключение.
- except: Блок, в котором указывается, как обработать возникшее исключение.
- else: Блок, который выполняется, если в блоке try не произошло исключений.
- finally: Блок, который выполняется всегда, независимо от того, произошло исключение или нет. Обычно используется для освобождения ресурсов.
from selenium import webdriver
from selenium.common.exceptions import NoSuchElementException, ElementNotInteractableException
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.options import Options
import time
options = Options()
options.add_argument("--headless=new")
options.add_argument("window-size=1920,1080")
driver = webdriver.Chrome(options=options)
driver.get("http://books.toscrape.com/")
try:
# Пытаемся найти элемент
element = driver.find_element(By.ID, 'search')
element.click()
except NoSuchElementException:
print("Элемент не найден")
except ElementNotInteractableException:
print("Элемент не доступен для взаимодействия")
else:
print("Элемент успешно найден и кликнут")
finally:
driver.quit()
- try: В этом блоке мы пытаемся найти элемент и кликнуть по нему.
- except NoSuchElementException: Если элемент не найден, это исключение перехватывается, и выводится сообщение "Элемент не найден".
- except ElementNotInteractableException: Если элемент не доступен для взаимодействия, перехватывается это исключение, и выводится сообщение "Элемент не доступен для взаимодействия".
- else: Этот блок выполняется, если не возникло исключений. В данном случае выводится сообщение "Элемент успешно найден и кликнут".
- finally: Этот блок выполняется всегда и используется для завершения работы драйвера и освобождения ресурсов.
Таким образом, обработка исключений позволяет сделать код более устойчивым и обеспечить корректное завершение программы даже при возникновении ошибок.
Ожидания играют важную роль в автоматизации тестирования веб-приложений, так как они помогают обеспечить корректное выполнение скриптов, особенно при работе с динамическим контентом. В Selenium существуют два основных типа ожиданий: имплицитные (implicit) и явные (explicit). Рассмотрим их более подробно.
Имплицитное ожидание устанавливает максимальное время ожидания для поиска элементов на странице. Это время будет использоваться при каждом вызове методов поиска элементов, таких как findElement
и findElements
. Если элемент не найден мгновенно, WebDriver продолжит поиск до истечения заданного времени.
Преимущества имплицитного ожидания:
- Простота использования: Устанавливается один раз и действует на все элементы.
- Удобство: Позволяет избежать использования явных пауз с помощью
time.sleep
, что делает тесты более гибкими и надежными.
Имплицитное ожидание полезно в ситуациях, когда элементы на странице загружаются с небольшой задержкой, но в целом достаточно предсказуемо.
Явные ожидания позволяют задать условия, при которых WebDriver будет ожидать выполнения определенного события или состояния элемента. Это более гибкий подход по сравнению с имплицитным ожиданием, так как можно настроить ожидание конкретных условий для каждого элемента.
Вариации явных ожиданий:
-
Ожидание видимости элемента: WebDriver будет ждать, пока элемент станет видимым на странице. Это полезно для элементов, которые могут быть загружены, но скрыты изначально.
-
Ожидание кликабельности элемента: Ожидание того, что элемент станет кликабельным (доступным для взаимодействия). Это важно для кнопок и ссылок, которые могут быть недоступны в момент загрузки страницы.
-
Ожидание присутствия элемента в DOM: Ожидание появления элемента в DOM, но не обязательно его видимости. Это полезно для проверки, что элемент загружен на страницу.
-
Ожидание исчезновения элемента: Ожидание, пока элемент исчезнет из DOM или станет невидимым. Это полезно для проверки завершения загрузки или выполнения действия.
-
Ожидание текста элемента: Ожидание, пока в элементе появится конкретный текст. Это полезно для элементов, которые динамически обновляются на странице.
Преимущества явных ожиданий:
- Точность: Позволяют задавать точные условия, что делает тесты более предсказуемыми.
- Гибкость: Можно настроить различные условия для разных элементов и сценариев.
Использование ожиданий в Selenium помогает автоматизаторам и тестировщикам создавать более стабильные и надежные тесты. Имплицитные ожидания обеспечивают общее время ожидания для всех элементов, что упрощает написание кода. Явные ожидания позволяют более гибко управлять процессом тестирования, устанавливая конкретные условия для взаимодействия с элементами.
Для парсинга ожидания также крайне важны, так как контент на страницах часто загружается асинхронно с помощью JavaScript. Ожидания позволяют дождаться полного отображения нужного контента перед его извлечением, что повышает точность и эффективность скриптов парсинга.
Таким образом, правильное использование ожиданий в Selenium является ключевым аспектом успешной автоматизации тестирования и парсинга веб-приложений, обеспечивая устойчивость к задержкам и асинхронным загрузкам контента.
Рассмотрим примеры кода для каждого из видов ожиданий на сайте Books to Scrape с подробными комментариями.
Имплицитное ожидание устанавливается один раз и действует для всех последующих операций поиска элементов.
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
# Настройка опций браузера
options = Options()
options.add_argument("--headless=new")
options.add_argument("window-size=1920,1080")
# Создание экземпляра веб-драйвера
driver = webdriver.Chrome(options=options)
# Установка имплицитного ожидания в 10 секунд
driver.implicitly_wait(10)
# Переход на сайт
driver.get("http://books.toscrape.com/")
# Попытка найти элемент
try:
search_box = driver.find_element(By.ID, 'search')
search_box.click()
except NoSuchElementException:
print("Элемент не найден")
finally:
driver.quit()
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
driver = webdriver.Chrome(options=options)
driver.get("http://books.toscrape.com/")
try:
# Ожидание видимости элемента с ID 'search'
search_box = WebDriverWait(driver, 10).until(
EC.visibility_of_element_located((By.ID, 'search'))
)
search_box.click()
except TimeoutException:
print("Элемент не стал видимым вовремя")
finally:
driver.quit()
driver = webdriver.Chrome(options=options)
driver.get("http://books.toscrape.com/")
try:
# Ожидание кликабельности элемента с классом 'product_pod'
product = WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.CLASS_NAME, 'product_pod'))
)
product.click()
except TimeoutException:
print("Элемент не стал кликабельным вовремя")
finally:
driver.quit()
driver = webdriver.Chrome(options=options)
driver.get("http://books.toscrape.com/")
try:
# Ожидание присутствия элемента с тегом 'h3' в DOM
element = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.TAG_NAME, 'h3'))
)
print("Элемент присутствует в DOM")
except TimeoutException:
print("Элемент не появился в DOM вовремя")
finally:
driver.quit()
driver = webdriver.Chrome(options=options)
driver.get("http://books.toscrape.com/")
try:
# Ожидание исчезновения элемента с ID 'loading'
WebDriverWait(driver, 10).until(
EC.invisibility_of_element_located((By.ID, 'loading'))
)
print("Элемент исчез из DOM")
except TimeoutException:
print("Элемент не исчез вовремя")
finally:
driver.quit()
driver = webdriver.Chrome(options=options)
driver.get("http://books.toscrape.com/")
try:
# Ожидание появления конкретного текста в элементе с классом 'title'
element = WebDriverWait(driver, 10).until(
EC.text_to_be_present_in_element((By.CLASS_NAME, 'title'), "Books to Scrape")
)
print("Текст элемента соответствует ожидаемому")
except TimeoutException:
print("Текст элемента не изменился вовремя")
finally:
driver.quit()
-
Имплицитное ожидание: Устанавливается одноразово и применяется ко всем элементам. Оно позволяет избежать необходимости явно указывать задержки в коде.
-
Ожидание видимости элемента: Ожидает, пока элемент станет видимым, что полезно для элементов, которые могут быть скрытыми при начальной загрузке страницы.
-
Ожидание кликабельности элемента: Ожидает, пока элемент станет доступным для клика. Полезно для кнопок и ссылок, которые могут быть временно недоступны.
-
Ожидание присутствия элемента в DOM: Проверяет, что элемент присутствует в DOM, но не обязательно видим. Полезно для проверки загрузки элементов.
-
Ожидание исчезновения элемента: Ожидает, пока элемент исчезнет из DOM, что может быть полезно для проверки завершения загрузки или выполнения действия.
-
Ожидание текста элемента: Ожидает, пока текст элемента изменится на ожидаемый. Полезно для проверки обновления контента на странице.
Эти примеры показывают, как можно использовать различные виды ожиданий в Selenium для создания более надежных и стабильных тестов.
Внедрение JavaScript в тестовые сценарии и сценарии парсинга с помощью Selenium WebDriver позволяет решить ряд задач, которые не всегда можно выполнить стандартными методами WebDriver. JavaScript дает возможность более гибко и эффективно взаимодействовать с элементами на веб-странице.
- Манипуляция DOM: JavaScript позволяет напрямую изменять DOM-структуру страницы, что полезно для тестирования динамического контента.
- Выполнение сложных сценариев: Некоторые действия могут быть выполнены только с помощью JavaScript, например, выполнение скроллинга, получение скрытых элементов и т.д.
- Ускорение тестов: Выполнение JavaScript-кода иногда быстрее, чем использование стандартных методов WebDriver, что позволяет ускорить выполнение тестов.
- Получение данных: JavaScript можно использовать для извлечения данных, которые не всегда доступны через стандартные методы WebDriver.
-
Скроллинг страницы:
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
Этот код прокручивает страницу до самого низа, что полезно для загрузки динамического контента или тестирования бесконечной прокрутки.
-
Извлечение скрытых элементов:
hidden_element = driver.execute_script("return document.querySelector('#hiddenElement');")
Этот код возвращает скрытый элемент, который нельзя найти стандартными методами WebDriver.
-
Клик по элементу:
element = driver.find_element(By.ID, 'element_id') driver.execute_script("arguments[0].click();", element)
Этот код выполняет клик по элементу с помощью JavaScript. Это полезно, когда стандартный метод
click()
не срабатывает из-за перекрытия элемента другим элементом или других причин. -
Изменение атрибутов элемента:
driver.execute_script("arguments[0].setAttribute('value', 'new value');", element)
Этот код изменяет значение атрибута элемента, что может быть полезно для тестирования форм и других интерактивных элементов.
-
Получение информации о видимости элемента:
is_visible = driver.execute_script("return arguments[0].offsetWidth > 0 && arguments[0].offsetHeight > 0;", element)
Этот код возвращает
True
, если элемент видим, иFalse
, если элемент скрыт. -
Обновление страницы и ожидание загрузки:
driver.execute_script("location.reload();") WebDriverWait(driver, 10).until(lambda driver: driver.execute_script("return document.readyState") == "complete")
Этот код обновляет страницу и ждет, пока она полностью загрузится.
-
Получение значений из элементов:
value = driver.execute_script("return arguments[0].value;", element)
Этот код возвращает значение элемента, например, текст из текстового поля.
-
Выполнение AJAX-запроса:
result = driver.execute_script(""" return fetch('https://api.example.com/data') .then(response => response.json()) .then(data => data); """)
Этот код выполняет AJAX-запрос и возвращает данные, что полезно для парсинга API.
Использование JavaScript в тестовых сценариях и сценариях парсинга с Selenium WebDriver позволяет решить множество задач, которые могут быть недоступны или сложны для выполнения стандартными методами WebDriver. Внедрение JavaScript дает возможность более гибко взаимодействовать с веб-страницей, манипулировать DOM, получать скрытые элементы, выполнять сложные действия и извлекать данные.
При автоматизации тестирования веб-приложений с помощью Selenium, важно не только уметь настраивать браузерные опции, но и работать с профилями браузера. Понимание различий между объектом опций (Options) и объектом профиля (Profile) помогает создавать более гибкие и эффективные сценарии автоматизации.
Объект опций в Selenium используется для настройки параметров запуска браузера. Эти параметры определяют, как браузер будет вести себя во время выполнения тестов. Например, можно указать запуск браузера в режиме "без головы" (headless), установить размеры окна браузера, включить режим инкогнито, задать пользовательский агент и многое другое. Основная цель опций – это конфигурация среды выполнения браузера, чтобы тесты могли выполняться в определенных условиях.
Объект профиля, с другой стороны, представляет собой более сложную концепцию, которая относится к настройкам и состоянию браузера, сохраненным между сессиями. Профиль браузера содержит всю информацию о пользовательских настройках, истории посещений, сохраненных паролях, куки-файлах, расширениях и других данных, которые можно сохранять и повторно использовать.
Разделение на объекты опций и профиля позволяет более точно и гибко управлять тестовой средой. Опции задают начальные параметры запуска, которые нужны для определенного теста или сценария, в то время как профиль сохраняет постоянные данные и настройки, которые могут быть важны для длительных тестовых сессий или специфических сценариев.
Опции включают в себя различные параметры, которые влияют на поведение браузера во время одной сессии. Это могут быть:
- Режим запуска браузера (headless, incognito).
- Настройки окна (размер, позиция).
- Пользовательские агенты.
- Блокировка всплывающих окон.
- Отключение уведомлений.
Профиль хранит данные, которые обычно накапливаются за время использования браузера. Это могут быть:
- История браузера.
- Куки и кэш.
- Сохраненные логины и пароли.
- Установленные расширения.
- Пользовательские настройки браузера (например, настройки безопасности и приватности).
Предположим, вы тестируете веб-приложение, которое требует аутентификации. Если использовать профиль, где уже сохранены логины и пароли, можно автоматизировать процесс входа без необходимости вводить данные вручную в каждом тесте. Также профиль можно использовать для тестирования с определенными расширениями браузера или сохранения состояния после выполнения ряда тестов.
Разделение понятий опций и профиля в Selenium позволяет создавать более точные и управляемые сценарии автоматизации. Опции помогают настроить браузер для конкретных условий тестирования, в то время как профиль сохраняет данные и настройки, необходимые для повторного использования и длительных сессий. Это делает процесс автоматизации более гибким и удобным, позволяя тестировщикам и разработчикам эффективно работать с разными аспектами браузерного окружения.
Использование куки-файлов для автоматизации процесса авторизации позволяет сохранить состояние сессии между запусками скрипта. Это позволяет избежать повторного ввода логина и пароля, если куки остаются актуальными.
Этот скрипт выполняет логин на воображаемом сайте и сохраняет куки в файл.
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.options import Options
import pickle
import time
# Настройка опций браузера
options = Options()
options.add_argument("--headless=new")
options.add_argument("window-size=1920,1080")
# Создание экземпляра веб-драйвера
driver = webdriver.Chrome(options=options)
# Переход на сайт
driver.get("https://example.com/login")
# Логин (замените селекторы и данные логина на актуальные)
username = driver.find_element(By.NAME, "username")
password = driver.find_element(By.NAME, "password")
login_button = driver.find_element(By.NAME, "login")
username.send_keys("myusername")
password.send_keys("mypassword")
login_button.click()
# Ждем, чтобы завершить процесс логина
time.sleep(5)
# Сохранение куки в файл
with open("cookies.pkl", "wb") as file:
pickle.dump(driver.get_cookies(), file)
driver.quit()
Этот скрипт загружает сохраненные куки и переходит на защищенную страницу без необходимости логина.
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.options import Options
import pickle
import time
# Настройка опций браузера
options = Options()
options.add_argument("--headless=new")
options.add_argument("window-size=1920,1080")
# Создание экземпляра веб-драйвера
driver = webdriver.Chrome(options=options)
# Переход на сайт для установки домена куки
driver.get("https://example.com")
# Загрузка куки из файла
with open("cookies.pkl", "rb") as file:
cookies = pickle.load(file)
for cookie in cookies:
driver.add_cookie(cookie)
# Переход на защищенную страницу
driver.get("https://example.com/protected-page")
# Проверяем доступность страницы
time.sleep(5)
print(driver.title) # Ожидаем, что мы уже залогинены и можем видеть заголовок защищенной страницы
driver.quit()
-
Шаг 1: Логин и сохранение куки:
- Настройка опций браузера: Создаем объект
Options
и задаем параметры запуска браузера. - Создание экземпляра веб-драйвера: Запускаем Chrome с заданными опциями.
- Переход на страницу логина: Открываем страницу логина воображаемого сайта.
- Логин: Находим поля ввода логина и пароля, заполняем их данными и нажимаем кнопку логина.
- Сохранение куки: Ждем завершения логина и сохраняем куки в файл
cookies.pkl
с помощью модуляpickle
. - Завершение работы драйвера: Закрываем браузер.
- Настройка опций браузера: Создаем объект
-
Шаг 2: Загрузка куки и доступ к сайту:
- Настройка опций браузера: Создаем объект
Options
и задаем параметры запуска браузера. - Создание экземпляра веб-драйвера: Запускаем Chrome с заданными опциями.
- Переход на сайт для установки домена куки: Открываем главную страницу сайта, чтобы установить домен для куки.
- Загрузка куки: Загружаем куки из файла и добавляем их в браузерную сессию.
- Переход на защищенную страницу: Переходим на защищенную страницу, для доступа к которой обычно требуется логин.
- Проверка доступности страницы: Проверяем, что заголовок страницы соответствует ожидаемому, что подтверждает успешную авторизацию.
- Завершение работы драйвера: Закрываем браузер.
- Настройка опций браузера: Создаем объект
Использование куки-файлов позволяет сохранять состояние сессии и ускорять процесс авторизации при повторных запусках скрипта, что особенно полезно при тестировании и парсинге защищенных страниц.
В примере с куки, который я предоставил, куки добавляются напрямую в драйвер, а не в профиль. Давайте разберемся, почему так и когда стоит использовать каждый подход.
Когда куки добавляются напрямую в драйвер, это делается для простоты и скорости выполнения задачи. Этот подход удобен в следующих случаях:
- Быстрое выполнение скрипта: Для одноразовых скриптов, где нужно быстро проверить авторизацию или доступ к странице.
- Миграция состояния между запусками: Для тестов, где важно сохранить текущее состояние сессии, но нет необходимости сохранять полный профиль пользователя.
- Динамическое управление сессией: Куки можно легко и быстро изменить или обновить между запусками скрипта.
Использование профиля браузера может быть предпочтительным в следующих случаях:
- Долгосрочное тестирование: Когда требуется сохранить все настройки, куки и историю браузера между многочисленными сессиями.
- Управление состоянием пользователя: Для тестов, которые требуют сохранения полных пользовательских данных, включая расширения, сохраненные пароли, историю и другие параметры.
- Консистентность окружения: Профиль гарантирует, что все настройки браузера остаются неизменными между запусками, что важно для консистентных тестов.
- Проще и быстрее: Добавление куки напрямую в драйвер – это быстрый и легкий способ обеспечить авторизацию без необходимости сложного управления профилем.
- Изоляция данных: Для коротких тестов или разовых скриптов использование профиля может быть избыточным и требовать больше времени на настройку и управление.
- Гибкость: Можно легко и быстро добавлять, изменять или удалять куки без необходимости изменять профиль.
Оба подхода – добавление куки напрямую в драйвер и использование профиля – имеют свои преимущества и недостатки. Выбор подхода зависит от специфики задачи:
- Для быстрых, разовых или краткосрочных тестов и скриптов добавление куки напрямую в драйвер является оптимальным решением.
- Для долгосрочных тестов и сценариев, требующих сохранения полного состояния браузера и пользовательских данных, использование профиля будет более подходящим.
Таким образом, для вашего конкретного примера с авторизацией через куки, добавление куки напрямую в драйвер было выбрано для простоты и наглядности примера.
Скачивание файлов через Selenium WebDriver может быть сложной задачей, особенно при использовании Google Chrome, так как настройки для автоматической загрузки файлов могут не всегда срабатывать корректно. В данном примере мы будем использовать Firefox, который предоставляет более надежный и проверенный способ настройки профиля для автоматической загрузки файлов.
Для того чтобы настроить Firefox на автоматическую загрузку файлов в указанную папку, необходимо изменить несколько параметров профиля браузера. Это позволяет избежать всплывающих окон и диалогов, требующих подтверждения действия.
from selenium import webdriver
import time
from selenium.webdriver.common.by import By
import os
# Настройка пути к текущей папке для скачивания
download_dir = os.path.abspath(".")
print(download_dir)
Здесь мы импортируем необходимые библиотеки и определяем переменную download_dir
, которая указывает на текущую папку для загрузки файлов. Путь преобразуется в абсолютный для обеспечения корректной работы.
# Создание объекта FirefoxOptions
options = webdriver.FirefoxOptions()
profile = webdriver.FirefoxProfile()
profile.set_preference("browser.download.folderList", 2) # 2 - пользовательская папка для загрузок
profile.set_preference("browser.download.dir", download_dir) # Путь к папке для загрузок
profile.set_preference("browser.helperApps.neverAsk.saveToDisk", "application/octet-stream,application/epub+zip,application/pdf,image/jpeg,image/png,text/plain,text/csv") # Типы файлов для автоматической загрузки
profile.set_preference("pdfjs.disabled", True) # Отключение встроенного просмотра PDF
options.profile = profile
browser.download.folderList
: Устанавливает папку для загрузок. Значение2
означает пользовательскую папку.browser.download.dir
: Указывает путь к папке для загрузок, заданный в переменнойdownload_dir
.browser.helperApps.neverAsk.saveToDisk
: Список MIME-типов файлов, которые будут автоматически загружаться без запроса.pdfjs.disabled
: Отключает встроенный просмотр PDF, чтобы PDF-файлы загружались напрямую.
# Запуск Firefox с указанными опциями
driver = webdriver.Firefox(options=options)
Создаем экземпляр драйвера Firefox с заданными настройками профиля.
# Открытие страницы
driver.get("https://cloud.mail.ru/public/FG24/BqdM22NZG")
# Найти и нажать на кнопку скачивания
download_button = driver.find_element(By.CLASS_NAME, "ViewerHeaderButton__title--sSLhK")
download_button.click()
Переходим на целевую страницу и находим кнопку для скачивания файла по классу ViewerHeaderButton__title--sSLhK
. Затем выполняем клик по кнопке, чтобы инициировать загрузку.
# Подождать некоторое время, чтобы файл успел загрузиться
time.sleep(10)
Используем time.sleep(10)
для ожидания завершения загрузки файла. Если файл большой, время ожидания нужно увеличить. Это простейший способ ожидания, но можно использовать более продвинутые методы, такие как отслеживание наличия файла в папке загрузки.
# Закрыть браузер
driver.quit()
Закрываем браузер и завершаем работу драйвера.
Этот пример демонстрирует, как настроить Firefox для автоматической загрузки файлов, используя Selenium WebDriver. Профиль браузера настраивается так, чтобы файлы загружались в указанную папку без дополнительных диалоговых окон. Это позволяет эффективно автоматизировать процесс скачивания файлов и ускорить сценарии тестирования и парсинга.