Клик по элементу с текстом в Puppeteer: методы и решения

Пройдите тест, узнайте какой профессии подходите

Я предпочитаю
0%
Работать самостоятельно и не зависеть от других
Работать в команде и рассчитывать на помощь коллег
Организовывать и контролировать процесс работы

Быстрый ответ

Совершить клик на элемент по его тексту в Puppeteer возможно с использованием XPath в сочетании с методом page.$x(). В качестве примера, рассмотрим клик на ссылку с текстом "Пример текста":

JS
Скопировать код
const [link] = await page.$x("//a[contains(text(), 'Пример текста')]");
if (link) await link.click();

Данный подход применим для элемента <a>, содержащего текст "Пример текста". XPath может быть адаптирован для разнообразных элементов и контента.

Кинга Идем в IT: пошаговый план для смены профессии

Работа со сложной структурой XPath

Будет полезно овладеть более сложными конструкциями XPath для справления с необычными ситуациями. К примеру, если требуется кликнуть по кнопке, содержащей уникальный текст и вложенной в элемент div с классом "elements":

JS
Скопировать код
const [button] = await page.$x("//div[@class='elements']/button[contains(., 'Текст кнопки')]");
if (button) await button.click();

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

Учтем пробелы и регистрозависимость

XPath в связке с функциями normalize-space() и translate() помогут справиться с излишними пробелами и разницей в регистрах:

JS
Скопировать код
const [button] = await page.$x("//button[contains(translate(normalize-space(.), 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'), 'текст кнопки')]");
if (button) await button.click();

Такой подход позволяет кликнуть по кнопке, не заботясь о регистрах букв и наличии пробелов.

Отказываемся от XPath в пользу селекторов с текстовым префиксом

С версии Puppeteer 18.0.0 стало возможным применять текстовые селекторы, которые могут быть проще XPath:

JS
Скопировать код
await page.click('text/Текст кнопки');

Текстовые селекторы идеально подходят для клика по невложенным текстовым элементам.

Управляем динамическим содержимым

Благодаря методам waitForXPath() и waitForFunction(), Puppeteer без проблем позволит дождаться появления элементов в динамичных веб-приложениях:

JS
Скопировать код
await page.waitForXPath("//button[contains(text(), 'Загрузить еще')]");
const [loadMoreButton] = await page.$x("//button[contains(text(), 'Загрузить еще')]");
if (loadMoreButton) await loadMoreButton.click();

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

JS
Скопировать код
await page.waitForFunction(
  text => document.body.innerText.includes(text),
  {},
  'Текст кнопки'
);
await page.click('button:contains("Текст кнопки")');

Следим за кавычками: продвинутый уровень

Если в текстах присутствуют кавычки, корректно их экранируйте:

JS
Скопировать код
const [button] = await page.$x("//button[contains(text(), \"Бургеры Боба\")]");
if (button) await button.click();

Используем CSS-селекторы с jQuery

Если в документе присутствует jQuery, можно использовать псевдоселектор :contains():

JS
Скопировать код
await page.click('button:contains("Возобновить")');

Визуализация

Вообразите Puppeteer как роботизированную руку, которая выбирает и нажимает кнопки на управляющей панели, усеянной различными надписями:

Markdown
Скопировать код
Панель управления (🎛️): [Старт ⏵, Стоп ⏹, Пауза ⏸, Возобновить ▶️]

Ее функция:

JS
Скопировать код
await page.click('button:contains("Возобновить")'); // 🤖 роботизированная рука тянется к кнопке "Возобновить ▶️"

Представление визуальной схемы:

Markdown
Скопировать код
🤖: [Ищу "Возобновить"...]
До: [⏵, ⏹, ⏸, ▶️]
После: *Клик* на [⏵, ⏹, ⏸, **👆▶️**]

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

Для более надежного взаимодействия с элементами иногда следует преобразовать NodeList в массив или использовать document.evaluate:

JS
Скопировать код
const elements = await page.evaluate(() => {
  const buttons = [...document.querySelectorAll('button')];
  return buttons.map(button => ({ text: button.textContent, node: button }));
});

const targetButton = elements.find(button => button.text.includes('Возобновить'));
if (targetButton) await targetButton.node.click();

Точность обеспечивается за счёт преобразования NodeList в массив, что предоставляет доступ к методам работы с массивами.

Факты и риски

Не стоит забывать, что XPath чувствителен к регистру и может оказаться ненадежным при изменении HTML-структуры. У разных версий Puppeteer могут быть различия в синтаксисе, поэтому регулярно просматривайте актуальную документацию.

Дополнительные рекомендации для умного кодера

  • Используйте result.iterateNext().click(), чтобы XPath последовательно обрабатывал потенциальные совпадения.
  • Воспользуйтесь библиотекой puppeteer-select для внедрения функционала, подобного псевдоселектору :contains в jQuery.
  • Для повышения точности ваших селекторов добавляйте классы родительских элементов, чтобы исключить неправильные клики по повторяющимся в тексте элементам.

Полезные материалы

  1. GitHub – puppeteer/puppeteer: Node.js API для Chrome — официальный репозиторий Puppeteer с полным списком API.
  2. Puppeteer | Puppeteer – page.click() функция — официальная документация Puppeteer на функцию page.click().
  3. XPath | MDN — документация MDN Web, описывающая XPath и нужные для выбора элементов с уникальным текстом.
  4. Руководство по CSS-селекторам — полное руководство по CSS-селекторам, используемым для выбора элементов в Puppeteer.
  5. Обучающее видео по работе с Puppeteer — YouTube урок по управлению веб-элементами с помощью Puppeteer.
  6. Puppeteer | Puppeteer – page.evaluate() метод — подробности о методе page.evaluate(), критически важном для доступа к DOM и манипулирования элементами в Puppeteer.
  7. Just a moment... – Обсуждение на Stack Overflow по клику на элементе с использованием Puppeteer — глубокое обсуждение на Stack Overflow, помогающее в реализации задач.