Как спарсить динамическую таблицу с SeleniumBase, если элементы исчезают при скролле

    При парсинге современных веб-страниц часто встречаются динамические таблицы, которые подгружают данные по мере прокрутки (infinite scroll). Специфика таких таблиц в том, что старые строки удаляются из DOM-дерева, а новые появляются. Это создаёт проблему: после скролла XPath-запросы к предыдущим элементам перестают работать. В этой статье разберём, как корректно спарсить динамическую таблицу с помощью SeleniumBase - удобной обёртки для Selenium.

    Почему элементы исчезают при скролле?

    Динамические таблицы часто реализованы с использованием виртуализации (например, библиотеки react-window или ag-Grid). Браузер хранит в DOM только те строки, которые видны в окне. При прокрутке невидимые строки удаляются, а новые добавляются. Это экономит память, но усложняет сбор данных.

    Основные подходы к парсингу

    1. Сбор данных до скролла

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

    2. Пагинация с перехватом данных из сети

    Часто динамические таблицы получают данные через AJAX-запросы. Используйте SeleniumBase для мониторинга сетевых запросов (через driver.requests или интеграцию с mitmproxy). Вы сможете перехватить JSON-ответы и спарсить их без необходимости скроллить страницу.

    from seleniumbase import Driver
    driver = Driver()
    driver.get('https://example.com/table')
    # Включить мониторинг запросов
    driver.start_capture_requests()
    # Выполнить скролл или действия
    driver.execute_script('window.scrollTo(0, document.body.scrollHeight)')
    # Получить перехваченные запросы
    for request in driver.requests:
        if 'api/data' in request.url:
            print(request.response.body)

    3. Скролл с немедленным сохранением

    Если перехват запросов невозможен, скролльте страницу маленькими шагами и сразу сохраняйте видимые элементы. Пример цикла:

    • Определите высоту страницы до скролла.
    • Выполните скролл на 500-800 пикселей.
    • Подождите загрузки новых данных (time.sleep или WebDriverWait).
    • Соберите все видимые строки таблицы по XPath.
    • Повторяйте, пока высота страницы не перестанет меняться.

    4. Использование JavaScript для принудительного сохранения DOM

    Можно выполнить JavaScript, который клонирует элементы перед их удалением:

    driver.execute_script('''
        var table = document.querySelector('div.table-container');
        var clone = table.cloneNode(true);
        clone.style.display = 'none';
        document.body.appendChild(clone);
    ''')

    Этот метод не всегда надёжен, так как виртуализация может не дать склонировать весь набор данных.

    Рекомендации по оптимизации

    • Используйте headless-режим для ускорения.
    • Настройте неявные ожидания (implicitly_wait).
    • При работе с большими объёмами данных сохраняйте результаты в базу данных или CSV после каждого шага скролла.

    Заключение

    Парсинг динамической таблицы с SeleniumBase требует понимания механизма виртуализации. Наиболее надёжный способ - перехват сетевых запросов. Если это невозможно, используйте пошаговый скролл с немедленным сохранением данных. Комбинируя эти методы, вы сможете собрать все строки таблицы, несмотря на их исчезновение из DOM.

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