Selenium – автоматизация браузера

онлайн тренажер по питону
Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Что такое Selenium и зачем он нужен

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

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

Ключевые возможности и преимущества Selenium

Кроссплатформенная поддержка браузеров

Selenium обеспечивает полную совместимость со всеми популярными браузерами, включая Google Chrome, Mozilla Firefox, Microsoft Edge, Safari и Opera. Это означает, что один и тот же код может работать в разных браузерах с минимальными изменениями.

Реалистичная имитация пользовательских действий

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

Гибкие методы поиска элементов

Selenium предоставляет множество способов поиска элементов на странице: по ID, классу, имени тега, CSS-селекторам, XPath-выражениям, тексту ссылок и другим атрибутам. Это обеспечивает максимальную гибкость при работе с различными типами веб-страниц.

Поддержка headless-режима

Возможность запуска браузера в headless-режиме (без графического интерфейса) делает Selenium идеальным инструментом для автоматизации на серверах, в контейнерах и CI/CD пайплайнах.

Расширенные возможности

Selenium умеет работать с множественными вкладками и окнами, обрабатывать JavaScript-алерты, управлять cookies и сессиями, настраивать прокси-серверы, делать скриншоты и сохранять HTML-код страниц.

Установка и настройка Selenium

Установка основной библиотеки

Для начала работы с Selenium необходимо установить основную библиотеку через pip:

pip install selenium

Загрузка и настройка драйверов браузеров

Для работы с каждым браузером требуется соответствующий драйвер. Наиболее популярным является ChromeDriver для браузера Chrome. Начиная с версии Chrome 115, рекомендуется использовать Chrome for Testing, который можно скачать с официального сайта Google.

Важно убедиться, что версия драйвера соответствует версии установленного браузера. Для автоматизации процесса можно использовать специальные инструменты, такие как webdriver-manager:

pip install webdriver-manager

Автоматическое управление драйверами

Современный подход к управлению драйверами предполагает использование менеджера драйверов:

from selenium import webdriver
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.chrome.service import Service

service = Service(ChromeDriverManager().install())
driver = webdriver.Chrome(service=service)

Основы работы с Selenium

Запуск браузера и базовые операции

Базовый пример запуска браузера и навигации по страницам:

from selenium import webdriver
from selenium.webdriver.chrome.options import Options

# Настройка опций браузера
options = Options()
options.add_argument('--no-sandbox')
options.add_argument('--disable-dev-shm-usage')

# Инициализация драйвера
driver = webdriver.Chrome(options=options)

# Навигация по страницам
driver.get("https://example.com")
print(f"Заголовок страницы: {driver.title}")
print(f"Текущий URL: {driver.current_url}")

# Закрытие браузера
driver.quit()

Управление навигацией

Selenium предоставляет полный контроль над навигацией браузера:

# Основные методы навигации
driver.get("https://example.com")  # Переход по URL
driver.refresh()                   # Обновление страницы
driver.back()                      # Возврат на предыдущую страницу
driver.forward()                   # Переход вперед по истории

# Получение информации о странице
page_title = driver.title
current_url = driver.current_url
page_source = driver.page_source

Поиск и взаимодействие с элементами

Методы поиска элементов

Selenium предлагает множество стратегий для поиска элементов на странице:

from selenium.webdriver.common.by import By

# Поиск по различным атрибутам
element_by_id = driver.find_element(By.ID, "username")
element_by_name = driver.find_element(By.NAME, "email")
element_by_class = driver.find_element(By.CLASS_NAME, "login-form")
element_by_tag = driver.find_element(By.TAG_NAME, "button")
element_by_css = driver.find_element(By.CSS_SELECTOR, ".navbar a[href='/login']")
element_by_xpath = driver.find_element(By.XPATH, "//input[@type='password']")
element_by_link_text = driver.find_element(By.LINK_TEXT, "Войти")
element_by_partial_link = driver.find_element(By.PARTIAL_LINK_TEXT, "Регистр")

# Поиск множественных элементов
elements = driver.find_elements(By.CLASS_NAME, "item")

Взаимодействие с формами и элементами

Selenium позволяет выполнять различные действия с найденными элементами:

# Работа с текстовыми полями
username_field = driver.find_element(By.ID, "username")
username_field.clear()                    # Очистка поля
username_field.send_keys("admin")         # Ввод текста

# Работа с кнопками
submit_button = driver.find_element(By.XPATH, "//button[@type='submit']")
submit_button.click()                     # Клик по кнопке

# Получение информации об элементе
element_text = submit_button.text
element_attribute = submit_button.get_attribute("class")
is_displayed = submit_button.is_displayed()
is_enabled = submit_button.is_enabled()
is_selected = submit_button.is_selected()

Работа с формами

Selenium упрощает работу с веб-формами:

# Поиск и отправка формы
form = driver.find_element(By.ID, "loginForm")
form.submit()  # Отправка формы

# Альтернативный способ - клик по кнопке отправки
submit_button = driver.find_element(By.XPATH, "//input[@type='submit']")
submit_button.click()

Работа с выпадающими списками и чекбоксами

Управление выпадающими списками

Для работы с элементами select Selenium предоставляет специальный класс:

from selenium.webdriver.support.ui import Select

# Поиск выпадающего списка
dropdown = driver.find_element(By.ID, "country")
select = Select(dropdown)

# Различные способы выбора опций
select.select_by_visible_text("Россия")           # По видимому тексту
select.select_by_value("RU")                      # По значению
select.select_by_index(0)                         # По индексу

# Получение информации о выбранных опциях
selected_option = select.first_selected_option
all_selected = select.all_selected_options
all_options = select.options

# Снятие выбора (для multiple select)
select.deselect_all()
select.deselect_by_visible_text("Россия")

Работа с чекбоксами и радиокнопками

# Работа с чекбоксами
checkbox = driver.find_element(By.ID, "agree")
if not checkbox.is_selected():
    checkbox.click()

# Работа с радиокнопками
radio_button = driver.find_element(By.XPATH, "//input[@type='radio'][@value='option1']")
radio_button.click()

Ожидания в Selenium

Неявные ожидания

Неявные ожидания устанавливают глобальное время ожидания для всех операций поиска элементов:

# Установка неявного ожидания
driver.implicitly_wait(10)  # Ожидание до 10 секунд

# Теперь все операции поиска элементов будут ждать до 10 секунд
element = driver.find_element(By.ID, "dynamic-element")

Явные ожидания

Явные ожидания предоставляют более точный контроль над ожиданием определенных условий:

from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

# Создание объекта ожидания
wait = WebDriverWait(driver, 10)

# Ожидание появления элемента
element = wait.until(
    EC.presence_of_element_located((By.ID, "success-message"))
)

# Ожидание кликабельности элемента
clickable_element = wait.until(
    EC.element_to_be_clickable((By.ID, "submit-button"))
)

# Ожидание видимости элемента
visible_element = wait.until(
    EC.visibility_of_element_located((By.CLASS_NAME, "alert"))
)

# Ожидание исчезновения элемента
wait.until(
    EC.invisibility_of_element_located((By.ID, "loading-spinner"))
)

Управление окнами и вкладками

Работа с множественными вкладками

Selenium позволяет управлять несколькими вкладками браузера:

# Открытие новой вкладки
driver.execute_script("window.open('https://example.com', '_blank');")

# Получение списка всех вкладок
window_handles = driver.window_handles

# Переключение между вкладками
driver.switch_to.window(window_handles[1])  # Переход на вторую вкладку
driver.switch_to.window(window_handles[0])  # Возврат на первую вкладку

# Закрытие текущей вкладки
driver.close()

# Переключение на оставшуюся вкладку
driver.switch_to.window(window_handles[0])

Работа с фреймами

# Переход во фрейм
driver.switch_to.frame("frame-name")  # По имени
driver.switch_to.frame(0)             # По индексу
frame_element = driver.find_element(By.ID, "frame-id")
driver.switch_to.frame(frame_element)  # По элементу

# Возврат в основной контент
driver.switch_to.default_content()

# Переход в родительский фрейм
driver.switch_to.parent_frame()

Обработка JavaScript-алертов

Работа с модальными окнами

from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

# Ожидание появления алерта
wait = WebDriverWait(driver, 10)
alert = wait.until(EC.alert_is_present())

# Получение текста алерта
alert_text = alert.text
print(f"Текст алерта: {alert_text}")

# Подтверждение алерта
alert.accept()

# Отклонение алерта (для confirm)
alert.dismiss()

# Ввод текста в prompt
alert.send_keys("Введенный текст")
alert.accept()

Продвинутые возможности

Выполнение JavaScript-кода

Selenium может выполнять произвольный JavaScript-код:

# Выполнение JavaScript
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")

# Возврат значения из JavaScript
page_height = driver.execute_script("return document.body.scrollHeight;")

# Взаимодействие с элементами через JavaScript
element = driver.find_element(By.ID, "hidden-button")
driver.execute_script("arguments[0].click();", element)

# Изменение свойств элементов
driver.execute_script("arguments[0].style.border='3px solid red';", element)

Работа с cookies

# Добавление cookie
driver.add_cookie({
    'name': 'session_id',
    'value': 'abc123',
    'domain': '.example.com',
    'path': '/',
    'secure': True,
    'httpOnly': False
})

# Получение всех cookies
all_cookies = driver.get_cookies()

# Получение конкретного cookie
session_cookie = driver.get_cookie('session_id')

# Удаление cookie
driver.delete_cookie('session_id')

# Удаление всех cookies
driver.delete_all_cookies()

Создание скриншотов

# Скриншот всей страницы
driver.save_screenshot("full_page.png")

# Скриншот конкретного элемента
element = driver.find_element(By.ID, "content")
element.screenshot("element.png")

# Скриншот в base64 (для интеграции с другими системами)
import base64
screenshot_base64 = driver.get_screenshot_as_base64()

Настройка headless-режима

Конфигурация безголового режима

from selenium import webdriver
from selenium.webdriver.chrome.options import Options

# Настройка Chrome для headless-режима
chrome_options = Options()
chrome_options.add_argument("--headless")
chrome_options.add_argument("--no-sandbox")
chrome_options.add_argument("--disable-dev-shm-usage")
chrome_options.add_argument("--disable-gpu")
chrome_options.add_argument("--window-size=1920,1080")

driver = webdriver.Chrome(options=chrome_options)

# Аналогично для Firefox
firefox_options = webdriver.FirefoxOptions()
firefox_options.add_argument("--headless")
firefox_driver = webdriver.Firefox(options=firefox_options)

Интеграция с тестовыми фреймворками

Использование с pytest

import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

@pytest.fixture
def driver():
    driver = webdriver.Chrome()
    yield driver
    driver.quit()

def test_login(driver):
    driver.get("https://example.com/login")
    
    username_field = driver.find_element(By.ID, "username")
    password_field = driver.find_element(By.ID, "password")
    submit_button = driver.find_element(By.ID, "submit")
    
    username_field.send_keys("testuser")
    password_field.send_keys("password123")
    submit_button.click()
    
    assert "dashboard" in driver.current_url

Использование с unittest

import unittest
from selenium import webdriver
from selenium.webdriver.common.by import By

class LoginTest(unittest.TestCase):
    def setUp(self):
        self.driver = webdriver.Chrome()
    
    def tearDown(self):
        self.driver.quit()
    
    def test_successful_login(self):
        self.driver.get("https://example.com/login")
        
        username_field = self.driver.find_element(By.ID, "username")
        password_field = self.driver.find_element(By.ID, "password")
        
        username_field.send_keys("admin")
        password_field.send_keys("password")
        
        submit_button = self.driver.find_element(By.ID, "submit")
        submit_button.click()
        
        self.assertIn("dashboard", self.driver.current_url)

if __name__ == "__main__":
    unittest.main()

Интеграция с другими библиотеками

Совместная работа с BeautifulSoup

from selenium import webdriver
from bs4 import BeautifulSoup

driver = webdriver.Chrome()
driver.get("https://example.com")

# Получение HTML-кода страницы
html = driver.page_source

# Парсинг с помощью BeautifulSoup
soup = BeautifulSoup(html, 'html.parser')

# Извлечение данных
title = soup.title.text
links = soup.find_all('a')
paragraphs = soup.find_all('p')

driver.quit()

Использование с pandas для анализа данных

import pandas as pd
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()
driver.get("https://example.com/table")

# Поиск таблицы
table = driver.find_element(By.ID, "data-table")

# Извлечение данных из таблицы
rows = table.find_elements(By.TAG_NAME, "tr")
data = []

for row in rows:
    cells = row.find_elements(By.TAG_NAME, "td")
    if cells:
        data.append([cell.text for cell in cells])

# Создание DataFrame
df = pd.DataFrame(data, columns=['Column1', 'Column2', 'Column3'])
print(df)

driver.quit()

Оптимизация производительности

Стратегии ускорения работы

from selenium import webdriver
from selenium.webdriver.chrome.options import Options

# Оптимизированные настройки Chrome
options = Options()
options.add_argument("--headless")
options.add_argument("--no-sandbox")
options.add_argument("--disable-dev-shm-usage")
options.add_argument("--disable-gpu")
options.add_argument("--disable-images")
options.add_argument("--disable-javascript")  # Если JS не нужен
options.add_argument("--disable-plugins")
options.add_argument("--disable-extensions")

# Отключение загрузки изображений
prefs = {
    "profile.managed_default_content_settings.images": 2,
    "profile.default_content_setting_values.notifications": 2
}
options.add_experimental_option("prefs", prefs)

driver = webdriver.Chrome(options=options)

Использование пула драйверов

from selenium import webdriver
from concurrent.futures import ThreadPoolExecutor
import threading

class WebDriverPool:
    def __init__(self, size=3):
        self.drivers = []
        self.lock = threading.Lock()
        
        for _ in range(size):
            driver = webdriver.Chrome()
            self.drivers.append(driver)
    
    def get_driver(self):
        with self.lock:
            if self.drivers:
                return self.drivers.pop()
            return None
    
    def return_driver(self, driver):
        with self.lock:
            self.drivers.append(driver)
    
    def close_all(self):
        for driver in self.drivers:
            driver.quit()

Таблица методов и функций Selenium

Категория Метод/Функция Описание Пример использования
Инициализация webdriver.Chrome() Запуск Chrome браузера driver = webdriver.Chrome()
  webdriver.Firefox() Запуск Firefox браузера driver = webdriver.Firefox()
  webdriver.Edge() Запуск Edge браузера driver = webdriver.Edge()
  webdriver.Safari() Запуск Safari браузера driver = webdriver.Safari()
Навигация driver.get(url) Переход по URL driver.get("https://example.com")
  driver.back() Возврат на предыдущую страницу driver.back()
  driver.forward() Переход вперед по истории driver.forward()
  driver.refresh() Обновление страницы driver.refresh()
Поиск элементов find_element(By.ID, id) Поиск по ID element = driver.find_element(By.ID, "username")
  find_element(By.NAME, name) Поиск по имени element = driver.find_element(By.NAME, "email")
  find_element(By.CLASS_NAME, class) Поиск по классу element = driver.find_element(By.CLASS_NAME, "button")
  find_element(By.TAG_NAME, tag) Поиск по тегу element = driver.find_element(By.TAG_NAME, "input")
  find_element(By.CSS_SELECTOR, selector) Поиск по CSS-селектору element = driver.find_element(By.CSS_SELECTOR, ".nav a")
  find_element(By.XPATH, xpath) Поиск по XPath element = driver.find_element(By.XPATH, "//button[@type='submit']")
  find_element(By.LINK_TEXT, text) Поиск по тексту ссылки element = driver.find_element(By.LINK_TEXT, "Войти")
  find_element(By.PARTIAL_LINK_TEXT, text) Поиск по частичному тексту ссылки element = driver.find_element(By.PARTIAL_LINK_TEXT, "Регистр")
  find_elements(locator) Поиск множественных элементов elements = driver.find_elements(By.CLASS_NAME, "item")
Взаимодействие element.click() Клик по элементу button.click()
  element.send_keys(text) Ввод текста input_field.send_keys("текст")
  element.clear() Очистка поля input_field.clear()
  element.submit() Отправка формы form.submit()
  element.text Получение текста элемента text = element.text
  element.get_attribute(attr) Получение атрибута value = element.get_attribute("class")
  element.is_displayed() Проверка видимости is_visible = element.is_displayed()
  element.is_enabled() Проверка активности is_active = element.is_enabled()
  element.is_selected() Проверка выбора is_checked = element.is_selected()
Информация о странице driver.title Заголовок страницы title = driver.title
  driver.current_url Текущий URL url = driver.current_url
  driver.page_source HTML-код страницы html = driver.page_source
Окна и фреймы driver.window_handles Список открытых окон handles = driver.window_handles
  driver.switch_to.window(handle) Переключение между окнами driver.switch_to.window(handles[1])
  driver.switch_to.frame(frame) Переход во фрейм driver.switch_to.frame("frame-name")
  driver.switch_to.default_content() Возврат в основной контент driver.switch_to.default_content()
  driver.switch_to.parent_frame() Переход в родительский фрейм driver.switch_to.parent_frame()
Ожидания driver.implicitly_wait(seconds) Неявное ожидание driver.implicitly_wait(10)
  WebDriverWait(driver, timeout) Создание объекта ожидания wait = WebDriverWait(driver, 10)
  wait.until(condition) Ожидание условия wait.until(EC.presence_of_element_located((By.ID, "element")))
Выпадающие списки Select(element) Создание объекта Select select = Select(dropdown)
  select.select_by_visible_text(text) Выбор по тексту select.select_by_visible_text("Опция")
  select.select_by_value(value) Выбор по значению select.select_by_value("option1")
  select.select_by_index(index) Выбор по индексу select.select_by_index(0)
  select.deselect_all() Снятие всех выборов select.deselect_all()
Алерты driver.switch_to.alert Переключение на алерт alert = driver.switch_to.alert
  alert.accept() Подтверждение алерта alert.accept()
  alert.dismiss() Отклонение алерта alert.dismiss()
  alert.text Текст алерта message = alert.text
  alert.send_keys(text) Ввод в prompt alert.send_keys("текст")
JavaScript driver.execute_script(script) Выполнение JavaScript driver.execute_script("window.scrollTo(0, 500)")
  driver.execute_script(script, *args) Выполнение JS с аргументами driver.execute_script("arguments[0].click()", element)
Скриншоты driver.save_screenshot(filename) Скриншот страницы driver.save_screenshot("page.png")
  element.screenshot(filename) Скриншот элемента element.screenshot("element.png")
  driver.get_screenshot_as_base64() Скриншот в base64 base64_img = driver.get_screenshot_as_base64()
Cookies driver.add_cookie(cookie_dict) Добавление cookie driver.add_cookie({"name": "session", "value": "123"})
  driver.get_cookies() Получение всех cookies cookies = driver.get_cookies()
  driver.get_cookie(name) Получение конкретного cookie cookie = driver.get_cookie("session")
  driver.delete_cookie(name) Удаление cookie driver.delete_cookie("session")
  driver.delete_all_cookies() Удаление всех cookies driver.delete_all_cookies()
Завершение работы driver.close() Закрытие текущего окна driver.close()
  driver.quit() Завершение сессии driver.quit()

Развертывание и автоматизация

Интеграция с CI/CD системами

Selenium легко интегрируется с популярными CI/CD системами:

GitHub Actions:

name: Selenium Tests
on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v2
    - name: Set up Python
      uses: actions/setup-python@v2
      with:
        python-version: 3.9
    - name: Install dependencies
      run: |
        pip install selenium pytest webdriver-manager
    - name: Run tests
      run: |
        pytest tests/

Jenkins Pipeline:

pipeline {
    agent any
    stages {
        stage('Test') {
            steps {
                sh 'pip install selenium pytest'
                sh 'pytest --html=report.html tests/'
            }
        }
    }
}

Использование в Docker

FROM python:3.9-slim

# Установка Chrome и ChromeDriver
RUN apt-get update && apt-get install -y \
    wget \
    gnupg \
    unzip \
    && wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add - \
    && echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list \
    && apt-get update \
    && apt-get install -y google-chrome-stable

# Установка зависимостей Python
COPY requirements.txt .
RUN pip install -r requirements.txt

# Копирование тестов
COPY tests/ /app/tests/
WORKDIR /app

# Запуск тестов
CMD ["python", "-m", "pytest", "tests/"]

Часто задаваемые вопросы

Что такое Selenium и для чего он используется?

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

Какие браузеры поддерживает Selenium?

Selenium поддерживает все основные браузеры: Google Chrome, Mozilla Firefox, Microsoft Edge, Safari, Opera и Internet Explorer. Для каждого браузера требуется соответствующий драйвер.

Можно ли использовать Selenium без графического интерфейса?

Да, Selenium поддерживает headless-режим для большинства браузеров. Это особенно полезно для автоматизации на серверах, в контейнерах Docker и CI/CD пайплайнах.

Подходит ли Selenium для веб-скрейпинга?

Selenium отлично подходит для скрейпинга динамических сайтов, где контент загружается через JavaScript. Однако для простых статических сайтов более эффективными могут быть инструменты как requests + BeautifulSoup.

Как ускорить работу Selenium?

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

Какие есть альтернативы Selenium?

Популярные альтернативы включают Playwright, Puppeteer, Cypress для тестирования, а также Scrapy с Splash для веб-скрейпинга.

Как обрабатывать динамический контент?

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

Можно ли запускать Selenium тесты параллельно?

Да, Selenium поддерживает параллельное выполнение тестов. Можно использовать pytest-xdist для pytest или TestNG для Java. Каждый тест должен использовать отдельный экземпляр WebDriver.

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

 

Новости