Python Selenium: парсинг динамических сайтов на примерах

    Команда Simple-Server
    03.06.2026
    22 мин

    Материал подготовлен командой Simple-Server для администраторов VPS и выделенных серверов. Команды и пути проверяйте на тестовой машине перед production.

    Введение в парсинг динамических сайтов с Selenium Python

    Большинство современных сайтов не отдают данные напрямую в виде статической HTML разметки. Страницы формируются «на лету» с использованием JavaScript.

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

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

    Почему стандартные методы парсинга могут не работать?

    • Динамическая подгрузка данных. Динамически подгружаемые данные иногда сложно отследить через веб-инспектор во вкладке запросов (например, из-за шифрования данных).

    • Использование WebSockets. Некоторые сервисы передают важную информацию через постоянное соединение по WebSockets. Стандартные методы не могут перехватить эти данные.

    • Сложные механизмы валидации. Когда нужно не только загрузить страницу, но и выполнить авторизацию или кликнуть на определенные элементы, без полноценного браузера не обойтись.

    Динамическая подгрузка данных. Динамически подгружаемые данные иногда сложно отследить через веб-инспектор во вкладке запросов (например, из-за шифрования данных).

    Использование WebSockets. Некоторые сервисы передают важную информацию через постоянное соединение по WebSockets. Стандартные методы не могут перехватить эти данные.

    Сложные механизмы валидации. Когда нужно не только загрузить страницу, но и выполнить авторизацию или кликнуть на определенные элементы, без полноценного браузера не обойтись.

    В таких случаях Selenium часто становится единственным решением.

    Когда стоит использовать Selenium для парсинга?

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

    Рассмотрим, в каких случаях использование эмуляции браузера будет оправдано:

    • Сложная навигация. Если контент появляется только после серии кликов или скроллов.

    • Интерактивность. Необходимо выполнить вход в личный кабинет, ввести CAPTCHA (или обойти ее), заполнить форму и так далее.

    • Точность. Если нужно получить данные в той же форме, в которой их видит реальный пользователь — чтобы не собирать данные частями по запросам во вкладке Network.

    Сложная навигация. Если контент появляется только после серии кликов или скроллов.

    Интерактивность. Необходимо выполнить вход в личный кабинет, ввести CAPTCHA (или обойти ее), заполнить форму и так далее.

    Точность. Если нужно получить данные в той же форме, в которой их видит реальный пользователь — чтобы не собирать данные частями по запросам во вкладке Network.

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

    Основные компоненты Selenium Python

    Для начала работы нужно понимать базовый набор инструментов и библиотек, которые позволят эмулировать браузер.

    Главная составляющая Selenium — это WebDriver, который взаимодействует с движком конкретного браузера (Chrome, Firefox, Edge и другими).

    Принцип работы следующий:

    1. Ваш скрипт на Python отправляет команды WebDriver (вроде «открой URL», «нажми на элемент» и т.д.).

    2. WebDriver передает эти команды соответствующему драйверу (например, chromedriver).

    3. Драйвер уже напрямую управляет браузером, совершая запрашиваемые действия.

    Ваш скрипт на Python отправляет команды WebDriver (вроде «открой URL», «нажми на элемент» и т.д.).

    WebDriver передает эти команды соответствующему драйверу (например, chromedriver).

    Драйвер уже напрямую управляет браузером, совершая запрашиваемые действия.

    Установка и начало работы с Selenium

    Примеры в статье разобраны на облачном сервере Simple-Server фиксированной конфигурации CPU 2 x 3.3 ГГц, RAM 2 ГБ, NVMe 40 ГБ, ОС Ubuntu 22.04. Используется Python 3.10. Код включает в себя использование Google Chrome, при необходимости можете использовать другой драйвер.

    Перед началом проверьте, что используемый браузер установлен в систему. Например:

    Если браузера нет в системе, его нужно установить. Для установки Google Chrome на Ubuntu используйте:

    sudo apt update wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb sudo apt install ./google-chrome-stable_current_amd64.deb -y

    Рекомендуем создать и активировать виртуальное окружение. Зачастую проекты, связанные с парсингом, впоследствии разворачиваются на серверах. Поэтому использование виртуального окружения поможет без труда согласовать версии нужных библиотек.

    Далее установите Selenium через pip:

    Подключите Selenium в своем скрипте и проверьте работоспособность:

    from selenium import webdriver options = webdriver.ChromeOptions() # Раскомментируйте следующие строки, если используете сервер без GUI и получаете ошибку “session not created: probably user data directory is already in use, please specify a unique value for --user-data-dir argument, or don't use --user-data-dir” # options.add_argument("--headless") # options.add_argument("--no-sandbox") # options.add_argument("--disable-dev-shm-usage") # Создаем объект браузера (в данном случае Chrome) driver = webdriver.Chrome(options=options) # Открываем страницу driver.get("https://simple-server.tech") # Получаем заголовок print(driver.title) # Завершаем работу driver.quit()

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

    На этом базовая настройка завершена. Далее можно перейти к настройке Chromedriver, выбору режима headless и другим расширенным возможностям Selenium Python.

    Chromedriver и Chromium: как выбрать и настроить?

    Chromedriver — это отдельное приложение (исполняемый файл), которое нужно скачать с официального сайта. Важно, чтобы версия Chromedriver соответствовала версии Chrome (или Chromium) на вашей системе. Если версии не совпадают, будут возникать проблемы совместимости.

    Для установки Chromedriver на Ubuntu можно использовать менеджер пакетов:

    apt-get install chromium-chromedriver

    Пользователи на Windows могут скачать chromedriver.exe с официального сайта.

    Шаги для согласования Chromedriver и Chromium между собой:

    1. Установить Chrome или Chromium.

    2. Скачать Chromedriver той же версии.

    3. Указать путь к Chromedriver в переменной окружения или прописать в коде:

    Установить Chrome или Chromium.

    Скачать Chromedriver той же версии.

    Указать путь к Chromedriver в переменной окружения или прописать в коде:

    from selenium import webdriver from selenium.webdriver.chrome.service import Service service = Service('/usr/bin/chromedriver') options = webdriver.ChromeOptions() options.add_argument("--headless") options.add_argument("--no-sandbox") options.add_argument("--disable-dev-shm-usage") # Создаем объект браузера (в данном случае Chrome) driver = webdriver.Chrome(service=service, options=options) # Открываем страницу driver.get("https://simple-server.tech") # Получаем заголовок print(driver.title) # Завершаем работу driver.quit()

    Основные функции библиотеки парсинга Selenium Python

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

    Метод .get(url) загружает нужный сайт:

    driver.get("https://example.com")

    Поиск элементов на странице

    Selenium позволяет находить элементы по разным критериям.

    from selenium.webdriver.common.by import By element = driver.find_element(By.TAG_NAME, "h1") # Поиск первого <h1> elements = driver.find_elements(By.CLASS_NAME, "product") # Поиск всех элементов с классом

    Получение текста и атрибутов

    Часто нужно получить текст элемента или ссылку.

    print(element.text) # Получение текста print(element.get_attribute("href")) # Получение ссылки

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

    Selenium может кликать и вводить текст.

    button = driver.find_element(By.ID, "submit") button.click() # Клик по кнопке input_field = driver.find_element(By.NAME, "q") input_field.send_keys("Selenium") # Ввод текста

    Иногда нужно выполнять JS-код вручную. Это используется для прокрутки страницы или обхода защиты от ботов.

    driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")

    Ожидания загрузки элементов

    Некоторые сайты загружают контент с задержкой, поэтому используется WebDriverWait.

    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.CLASS_NAME, "price")))

    Некоторые сайты открывают данные в новых вкладках. Следующая функция используется для работы с несколькими окнами.

    tabs = driver.window_handles driver.switch_to.window(tabs[1]) # Переключение на вторую вкладку

    Один из наиболее популярных режимов — headless, то есть без отображения графического интерфейса. Этот режим полезен:

    • На серверах без установленного окружения рабочего стола (X11, Wayland).

    • Для снижения нагрузки: отсутствие отрисовки интерфейса значительно экономит ресурсы.

    На серверах без установленного окружения рабочего стола (X11, Wayland).

    Для снижения нагрузки: отсутствие отрисовки интерфейса значительно экономит ресурсы.

    Пример запуска в headless-режиме:

    from selenium import webdriver from selenium.webdriver.chrome.options import Options options = Options() options.add_argument('--headless') driver = webdriver.Chrome(options=options)

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

    Почему сайты блокируют headless-браузеры?

    Многие сайты пытаются защититься от автоматизированных ботов, анализируя поведение пользователя и сигнатуры браузера. При запуске в headless-режиме Chrome сообщает о себе некоторыми особыми значениями. Эти данные могут сигнализировать сайту, что перед ним не реальный пользователь.

    Если вы встретились с подобной проблемой, то это повод ознакомиться с условиями использования сайта-донора. Нужно остановить работу, если сбор данных нарушает правила.

    Дебаг-порт в Selenium: как отслеживать ошибки?

    При автоматизации тестирования веб-приложений с Selenium в Python иногда возникает необходимость детального анализа страниц, выполняемого JavaScript и сетевых запросов. Конечно, при отладке алгоритма на локальной машине вы можете не использовать headless режим и использовать окно браузера, с которым работает Selenium. Но для отладки программ в headless-режиме пригодится удаленная отладка (remote debugging).

    Режим удаленной отладки позволяет подключаться к браузеру через DevTools и следить за происходящими процессами. Такой подход особенно полезен при нестабильной загрузке элементов, неожиданных редиректах и сложных сценариях, где стандартных логов недостаточно.

    Для активации пропишите следующую опцию перед запуском драйвера:

    chrome_options.add_argument("--remote-debugging-port=9222")

    В Google Chrome перейдите на страницу chrome://inspect. Когда скрипт с Selenium запущен на стандартном порте 9222, Вы увидите доступный драйвер для подключения. Нажмите кнопку «inspect».

    Вы увидите стандартный интерфейс DevTools в Google Chrome и экран, с которым в данный момент взаимодействует Selenium.

    Настройка окружения и сервера для парсинга

    Когда объем данных большой, а парсинг запускается регулярно, важно правильно подобрать аппаратные ресурсы и ПО.

    Выбор конфигурации сервера для эмуляции браузера для парсинга через Selenium

    Требования к серверу зависят от:

    • Одновременного количества потоков. Если вы параллельно поднимаете десятки инстансов браузера, требуется больше ядер CPU и памяти.

    • Типа данных. Некоторые сайты тяжеловесны, содержат много JavaScript; браузеру нужно больше времени и ресурсов, чтобы все отрисовать.

    • Частоты обновления. Если парсинг запускается раз в день — можно обойтись дешевым VPS. Если же нужен непрерывный сбор данных, придется подумать о более производительных решениях.

    Одновременного количества потоков. Если вы параллельно поднимаете десятки инстансов браузера, требуется больше ядер CPU и памяти.

    Типа данных. Некоторые сайты тяжеловесны, содержат много JavaScript; браузеру нужно больше времени и ресурсов, чтобы все отрисовать.

    Частоты обновления. Если парсинг запускается раз в день — можно обойтись дешевым VPS. Если же нужен непрерывный сбор данных, придется подумать о более производительных решениях.

    Для расчета конфигурации можно использовать следующие параметры:

    • Оперативная память (RAM) : каждый браузер в среднем потребляет от 200 до 500 МБ. На десятки параллельных запущенных браузеров нужно уже несколько гигабайт.

    • CPU : минимум 2–4 ядра. Если нужно масштабироваться, имеет смысл взять 8+ ядер, чтобы распределить нагрузку.

    • Диск (SSD) : у Selenium большие требования к скорости чтения-записи, особенно если есть логирование и временные файлы.

    Оперативная память (RAM) : каждый браузер в среднем потребляет от 200 до 500 МБ. На десятки параллельных запущенных браузеров нужно уже несколько гигабайт.

    CPU : минимум 2–4 ядра. Если нужно масштабироваться, имеет смысл взять 8+ ядер, чтобы распределить нагрузку.

    Диск (SSD) : у Selenium большие требования к скорости чтения-записи, особенно если есть логирование и временные файлы.

    Облачная инфраструктура Simple-Server предоставляет возможность создать облачный VPS-сервер с рекомендуемой конфигурацией (CPU 2 x 3.3 ГГц, RAM 2 ГБ, NVMe 40 ГБ) стоимостью 850 рублей в месяц. Можно попробовать использовать сервера с конфигурацией ниже, но стабильность работы Selenium в этом случае не будет гарантирована.

    Улучшение стабильности работы Selenium Python на серверах

    Следующие параметры помогают избежать ошибок и ограничений при запуске браузера.

    НастройкаЧто она делает?Почему это важно?
    chrome_options.add_argument("--disable-gpu")Отключает аппаратное ускорение через GPU.Полезно при запуске в headless-режиме, так как без GPU могут возникать ошибки рендеринга.
    chrome_options.add_argument("--disable-dev-shm-usage")Использует /tmp вместо /dev/shm (общая память между процессами в Linux).При запуске в контейнерах Docker стандартный /dev/shm имеет ограниченный размер, что может вызывать сбои.
    chrome_options.add_argument("--no-sandbox")Отключает изолированную среду (sandbox) Chrome.Позволяет запускать браузер без ошибок в контейнерах и виртуальных машинах.

    Отключает аппаратное ускорение через GPU.

    Полезно при запуске в headless-режиме, так как без GPU могут возникать ошибки рендеринга.

    Использует /tmp вместо /dev/shm (общая память между процессами в Linux).

    При запуске в контейнерах Docker стандартный /dev/shm имеет ограниченный размер, что может вызывать сбои.

    Отключает изолированную среду (sandbox) Chrome.

    Позволяет запускать браузер без ошибок в контейнерах и виртуальных машинах.

    Как обойти блокировки и капчи при парсинге через Selenium?

    Воспользуйтесь следующими советами, чтобы обходить антибот системы:

    Настройки для базовой маскировки

    Отключение флага enable-automation

    chrome_options.add_experimental_option("excludeSwitches", ["enable-automation"])

    Что делает? Отключает флаг enable-automation, который указывает, что браузер запущен через Selenium.

    Почему важно? Многие сайты проверяют этот флаг через navigator.webdriver и могут сразу заблокировать пользователя.

    Отключение Selenium Automation Extension

    chrome_options.add_experimental_option("useAutomationExtension", False)

    Что делает? Отключает автоматическое расширение Selenium Automation Extension, которое браузер добавляет при запуске.

    Почему важно? Некоторые сайты проверяют загруженные расширения и могут заметить Selenium.

    Отключение функции AutomationControlled

    chrome_options.add_argument("--disable-blink-features=AutomationControlled")

    Что делает? Отключает специальную функцию Blink (рендеринг-движок Chrome), которая помечает браузер как управляемый автоматизированными инструментами.

    Почему важно? Некоторые сайты используют navigator.webdriver для определения автоматизированного доступа.

    chrome_options.add_argument("--disable-webrtc")

    Что делает? Отключает WebRTC, который может раскрыть реальный IP-адрес пользователя.

    Почему важно? Некоторые сайты отслеживают WebRTC-запросы, чтобы обнаружить подмену IP-адреса.

    Если сайт блокирует ваш IP, стоит проксировать запросы через разные серверы.

    Для подключения прокси без авторизации нужно добавить дополнительный аргумент.

    from selenium import webdriver from selenium.webdriver.chrome.service import Service from selenium.webdriver.chrome.options import Options proxy = "123.45.67.89:8080" # IP:PORT прокси chrome_options = Options() chrome_options.add_argument(f"--proxy-server={proxy}") driver = webdriver.Chrome(service=Service("chromedriver"), options=chrome_options) driver.get("https://www.whatismyipaddress.com/")

    Для прокси с авторизацией процесс подключения чуть сложнее. Тут поможет Selenium Wire — расширение для стандартного Selenium, которое позволяет работать с HTTP/HTTPS-запросами во время работы веб-драйвера.

    Установите библиотеку через pip:

    pip install selenium-wire

    Подключить такой вид прокси можно с помощью следующего примера:

    import time from seleniumwire import webdriver proxy_host = "123.45.67.89" proxy_port = "8080" proxy_user = "user" proxy_pass = "password" options = { 'proxy': { 'http': f'http://{proxy_user}:{proxy_pass}@{proxy_host}:{proxy_port}', 'https': f'https://{proxy_user}:{proxy_pass}@{proxy_host}:{proxy_port}', 'no_proxy': 'localhost,127.0.0.1' } } driver = webdriver.Chrome(seleniumwire_options=options) driver.get("https://www.whatismyipaddress.com/") time.sleep(5) driver.close() driver.quit()

    Добавляйте задержки между кликами и прокрутками, имитируя поведение реального пользователя.

    Предпочтительным способом реализации задержек является использование Expected Conditions. Скрипт автоматически продолжит работу, если обнаружит в DOM-дереве выбранный элемент.

    from selenium import webdriver 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() driver.get("https://example.com") # Ждём, пока кнопка станет кликабельной (до 10 секунд) wait = WebDriverWait(driver, 10) button = wait.until(EC.element_to_be_clickable((By.ID, "login-btn"))) button.click() # Только после появления элемента

    Другой способ — использовать примитивные задержки через time.sleep(). Но его проблема в том, что он не учитывает динамическое появление элементов.

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

    from selenium import webdriver from selenium.webdriver.chrome.options import Options chrome_options = Options() chrome_options.add_argument("user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36") driver = webdriver.Chrome(options=chrome_options) driver.get("https://www.whatismybrowser.com/")

    Если знакомы с библиотекой fakeua, которая каждый раз генерирует случайный User-Agent, то можно применить её функционал в этом случае.

    from fakeua import UserAgent ua = UserAgent() random_user_agent = ua.random() print(f"Используем User-Agent: {random_user_agent}") chrome_options.add_argument(f"user-agent={random_user_agent}")

    Интегрируйте сервисы для решения капчи

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

    1. Сделайте скриншот капчи. Или используйте метод, предлагаемый сервисом решения капчи.

    2. Отправьте изображение сервису через API.

    3. Получите ответ.

    4. Выполните целевое действие — вставка ответа, выбор картинок, проведение по слайдеру.

    Сделайте скриншот капчи. Или используйте метод, предлагаемый сервисом решения капчи.

    Отправьте изображение сервису через API.

    Выполните целевое действие — вставка ответа, выбор картинок, проведение по слайдеру.

    Сохранение и отправка данных после парсинга

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

    Запись данных в Excel (xlsx, csv) через pandas

    Сперва установите библиотеку pandas:

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

    Рассмотрим пример сохранения в CSV:

    import pandas as pd # вместо data подставьте список с полученными данными data = [ {"product_name": "Товар 1", "price": 100}, {"product_name": "Товар 2", "price": 200}, {"product_name": "Товар 3", "price": 300} ] df = pd.DataFrame(data) df.to_csv("results.csv", index=False, encoding="utf-8")

    Для экспорта в Excel используйте функцию to_excel():

    df.to_excel("results.xlsx", index=False)

    Использование MySQL и SQLite для хранения результатов

    Если нужно сохранять большие объёмы данных или использовать их для последующего анализа, удобнее сразу класть их в базу данных.

    SQLite — локальная файловая база данных, не требует отдельного сервера. Подробно о ней мы говорили в другом руководстве.

    В последних версиях Python модуль уже встроен.

    import sqlite3 conn = sqlite3.connect("results.db") cursor = conn.cursor() # пропишите структуру базы данных в SQL запросе cursor.execute("CREATE TABLE IF NOT EXISTS products (name TEXT, price INTEGER)") # вместо data подставьте список с полученными данными data = [("Товар 1", 100), ("Товар 2", 200)] # функция executemany() массово импортирует данные в БД cursor.executemany("INSERT INTO products VALUES (?, ?)", data) conn.commit() conn.close()

    В случае с MySQL ситуация похожа. Прежде установим библиотеку для работы с СУБД:

    pip install mysql-connector-python

    Процесс импорта данных совершенно идентичен, а подключение отличается:

    import mysql.connector conn = mysql.connector.connect( host="localhost", user="username", password="password", database="my_db" ) cursor = conn.cursor()

    Автоматическая отправка данных через Telegram-бот

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

    Парсер в этом случае удобно реализовать совместно с Telegram-ботом. Используем для этого фреймворк aiogram. Сперва установим его:

    Нужно зарегистрировать бота: мы уже говорили об этом в другой статье. Полученный токен нужно вставить как значение константы TOKEN:

    import asyncio import logging from aiogram import Bot, Dispatcher from selenium import webdriver from selenium.webdriver.chrome.options import Options from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC TOKEN = "TELEGRAM_BOT_TOKEN" CHAT_ID = "CHAT_ID" URL = "https://tickets.example.com/event/1234" CHECK_INTERVAL = 60 # Интервал проверки билетов (в секундах) logging.basicConfig(level=logging.INFO) bot = Bot(token=TOKEN) dp = Dispatcher() class TicketNotifier: def __init__(self): self.driver = self.init_selenium() self.last_status = False # Запоминаем предыдущее состояние (чтобы не отправлять одно и то же) def init_selenium(self): """ Инициализация headless Selenium """ options = Options() options.add_argument("--headless") options.add_argument("--disable-gpu") options.add_argument("--no-sandbox") options.add_argument("--disable-dev-shm-usage") return webdriver.Chrome(options=options) def parse_site(self): """ Парсинг сайта на наличие билетов """ try: self.driver.get(URL) wait = WebDriverWait(self.driver, 10) element = wait.until(EC.presence_of_element_located((By.CLASS_NAME, "ticket-available"))) return "Билеты в наличии" in element.text except Exception as e: logging.warning(f"Ошибка парсинга: {e}") return False async def check_tickets(self): """ Фоновая задача для проверки билетов """ while True: available = self.parse_site() if available and not self.last_status: # Если билеты появились впервые await self.notify() self.last_status = True # Запоминаем, что уже отправляли сообщение elif not available: self.last_status = False # Если билетов нет, сбрасываем статус await asyncio.sleep(CHECK_INTERVAL) async def notify(self): """ Отправка уведомления в Telegram-чат """ message = f"🎟 Билеты на мероприятие появились в продаже! 🔥\n[Купить билет]({URL})" try: await bot.send_message(CHAT_ID, message, parse_mode="Markdown") logging.info(f"Уведомление отправлено в чат {CHAT_ID}") except Exception as e: logging.warning(f"Ошибка отправки сообщения: {e}") async def run(self): """ Запуск фоновой задачи и Telegram-бота """ asyncio.create_task(self.check_tickets()) # Фоновая задача для парсинга await dp.start_polling(bot) if __name__ == "__main__": notifier = TicketNotifier() asyncio.run(notifier.run())

    Основные ошибки при парсинге Selenium Python и их решения

    Ошибка или симптомПричинаРешение
    NoSuchElementException при поиске элементаЭлемент ещё не успел прогрузиться или находится в другом фрейме.используйте WebDriverWait и expected_conditions, либо переключитесь в нужный iframe.

    Если элемент внутри фрейма:
    driver.switch_to.frame("frame_name").
    Версии Chromedriver и Chrome не совпадают:
    «ChromeDriver not found» или «This version of ChromeDriver only supports Chrome version X». | — | Вручную скачайте подходящую версию с официального сайта или обновите браузер, чтобы он соответствовал драйверу.
    Пустые данные при попытке прочитать текст элементов. | Код слишком быстро завершается (контент не успевает загрузиться). | Добавляйте небольшие задержки или используйте «умные ожидания» (WebDriverWait). Не злоупотребляйте time.sleep(), лучше ориентироваться на реальное появление элементов.
    «Permission denied» или «Sandbox» ошибки на серверах Linux | Запущено в режиме контейнера или без соответствующих прав. | Добавьте параметры --no-sandbox и --disable-dev-shm-usage в chrome_options, либо настройте права пользователя в Docker.

    NoSuchElementException при поиске элемента

    Элемент ещё не успел прогрузиться или находится в другом фрейме.

    используйте WebDriverWait и expected_conditions, либо переключитесь в нужный iframe.

    Если элемент внутри фрейма:
    driver.switch_to.frame("frame_name").

    Версии Chromedriver и Chrome не совпадают:
    «ChromeDriver not found» или «This version of ChromeDriver only supports Chrome version X».

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

    Пустые данные при попытке прочитать текст элементов.

    Код слишком быстро завершается (контент не успевает загрузиться).

    Добавляйте небольшие задержки или используйте «умные ожидания» (WebDriverWait). Не злоупотребляйте time.sleep(), лучше ориентироваться на реальное появление элементов.

    «Permission denied» или «Sandbox» ошибки на серверах Linux

    Запущено в режиме контейнера или без соответствующих прав.

    Добавьте параметры --no-sandbox и --disable-dev-shm-usage в chrome_options, либо настройте права пользователя в Docker.

    Альтернативы Selenium: когда использовать другие инструменты?

    На рынке существуют популярные альтернативы Selenium:

    • requests + BeautifulSoup
      Актуально, если страница не генерируется динамически, а вся нужная информация доступна в исходном HTML.

    requests + BeautifulSoup
    Актуально, если страница не генерируется динамически, а вся нужная информация доступна в исходном HTML.

    Плюсы : выше скорость, меньше потребление ресурсов, удобная обработка HTML.

    Минусы : не подходит для сложных сценариев (авторизация через JS, сложные клики).

    • Playwright
      Более современный инструмент с поддержкой разных языков (включая Python). Может работать в headless-режиме, имеет встроенные методы для обхода блокировок.

    Playwright
    Более современный инструмент с поддержкой разных языков (включая Python). Может работать в headless-режиме, имеет встроенные методы для обхода блокировок.

    Плюсы : быстрая многопоточность, удобные ожидания.

    Минусы : относительно молодая библиотека, чуть меньше готовых примеров, чем у Selenium.

    • Puppeteer
      Изначально разработан для Node.js (JavaScript), но существует Python-обёртка.

    Puppeteer
    Изначально разработан для Node.js (JavaScript), но существует Python-обёртка.

    Плюсы : нативная интеграция с Chrome DevTools.

    Минусы : Python-версия не такая стабильная, как оригинальная на JS.

    • Scrapy
      Классический инструмент для больших парсинг-проектов, где важно удобное управление пауками (spiders), логирование и масштабируемость.

    Scrapy
    Классический инструмент для больших парсинг-проектов, где важно удобное управление пауками (spiders), логирование и масштабируемость.

    Плюсы : легко управлять множеством URL, есть встроенные механизмы для работы с pipelin’ами данных.

    Минусы : плохо подходит для сложных динамических сайтов (без надстроек).


    Нужен сервер для практики? Арендуйте VPS/VDS в России — root-доступ, NVMe, DDoS-защита и поддержка 24/7.

    VPS для проекта

    VPS с root-доступом, NVMe и поддержкой 24/7 на Simple-Server.

    StarterVDS

    490₽

    в месяц

    1 ядро

    1 ГБ RAM

    20 ГБ NVMe

    • 1 IPv4
    • KVM
    • Root-доступ
    • Безлимитный трафик
    Заказать VPS
    Рекомендуем

    PerformanceVDS

    1190₽

    в месяц

    2 ядра

    4 ГБ RAM

    60 ГБ NVMe

    • 1 IPv4
    • KVM
    • Root-доступ
    • Базовая DDoS-защита
    Заказать VPS

    Нужна другая конфигурация или чистый VPS без панели?

    Все тарифы VPS

    Похожие статьи, которые могут быть вам интересны