2025, Sep 20 05:01
Как перейти на нужную страницу в jQuery‑пагинации через Selenium
Как в Selenium перейти к странице jQuery‑пагинации без перебора: поменять data.page у li и кликнуть родным обработчиком. Объясняем, почему g.show не работает.
Прыгать по сотням или тысячам результатов с разбиением на страницы в Selenium — мучение, если интерфейс показывает только кнопки «вперёд/назад». Когда пагинация завязана на JavaScript, простого клика по номеру может не хватить, а вызовы внутренних функций вроде g.show(...) извне страницы часто не срабатывают. Ниже — практичный способ попасть на конкретную страницу без перебора всех подряд.
Сценарий
Интерфейс пагинации — это список элементов <li>, на каждый из которых повешен обработчик клика JavaScript. В коде страницы нажатие на элемент запускает логику вида g.show(parseInt(m.data("page"))). Ключевая деталь: номер страницы берётся не из видимого текста элемента, а из данных, которые jQuery хранит у этого <li>.
Почему прямой вызов g.show не работает
Заманчиво попробовать получить элемент пагинации и выполнить что-то вроде arguments[0].g.show(...). Это не сработает, потому что g — переменная, созданная внутри setupEvents, и существует только в области видимости этой функции. JavaScript, выполняемый из Selenium, запускается в глобальном контексте, поэтому arguments[0].g неопределён, и вместо перехода вы получаете TypeError.
Просмотр данных и обработчиков, прикреплённых jQuery
В инструментах разработчика, если исследовать элемент пагинации <li> через $._data($('#stat_pagination > li:nth-child(9)')[0]), видно, что jQuery прикрепил к элементу и обработчики событий, и данные. Объект data включает текущий индекс страницы, например data: { page: 7, pageType: "page" }, а обработчик клика использует это значение, решая, какую страницу показывать. То есть целевая страница берётся из jQuery-свойства data.page, а не из текста ссылки.
Практическое решение на Selenium + jQuery
Короткий путь простой: переписать data.page у существующего, кликабельного <li>, затем кликнуть по этому <li>. Так вы переиспользуете штатный обработчик клика на странице и сразу переходите к нужному номеру.
target_page = 4200
nav_item_selector = '#stat_pagination > li:nth-child(9)'
nav_item = WebDriverWait(session, 3).until(
    EC.element_to_be_clickable((By.CSS_SELECTOR, nav_item_selector))
)
js_patch = "$._data( $('" + nav_item_selector + "')[0]).data.page=" + str(target_page) + ";"
session.execute_script(js_patch)
session.execute_script("arguments[0].click();", nav_item)
Эта последовательность делает две вещи. Сначала она задаёт в jQuery-данных выбранного элемента пагинации data.page нужный номер страницы. Затем кликает по тому же элементу, тем самым вызывает родной обработчик, который читает обновлённое data.page и переходит на эту страницу.
Почему прежний подход не сработал
Попытка вызвать arguments[0].g.show(...) терпит неудачу, потому что переменная g существует только внутри setupEvents, где она определена и используется для навешивания обработчиков. Эта область видимости не выходит в глобальный контекст, поэтому вызов из Selenium не находит g и выбрасывает ошибку. Изменение прикреплённых данных и клик по элементу работают, потому что задействуют уже привязанный к элементу обработчик.
Зачем этот приём
Когда сайт прячет логику навигации в JavaScript, «просто кликни» часто не отражает, какое состояние реально использует код. В данном случае рабочим входом является свойство jQuery data.page. Подправив это состояние и дав штатному обработчику сделать своё дело, вы избегаете реверс‑инжиниринга больших скриптов и попыток вызвать неглобальные функции, недоступные для JavaScript, исполняемого из Selenium.
Итоги
Для пагинации на jQuery самый быстрый путь к нужной странице — посмотреть jQuery-данные элемента, изменить значение page и вызвать клик. Это сохраняет нативный поток событий сайта и делает автоматизацию точной и экономной, особенно когда нужно продолжить работу далеко в длинном списке результатов.
Статья основана на вопросе на StackOverflow от StoneDogGaul и ответе StoneDogGaul.