Клик по элементу с текстом в Puppeteer: методы и решения
Быстрый ответ
Совершить клик на элемент по его тексту в Puppeteer возможно с использованием XPath в сочетании с методом page.$x()
. В качестве примера, рассмотрим клик на ссылку с текстом "Пример текста":
const [link] = await page.$x("//a[contains(text(), 'Пример текста')]");
if (link) await link.click();
Данный подход применим для элемента <a>
, содержащего текст "Пример текста". XPath может быть адаптирован для разнообразных элементов и контента.
Работа со сложной структурой XPath
Будет полезно овладеть более сложными конструкциями XPath для справления с необычными ситуациями. К примеру, если требуется кликнуть по кнопке, содержащей уникальный текст и вложенной в элемент div
с классом "elements":
const [button] = await page.$x("//div[@class='elements']/button[contains(., 'Текст кнопки')]");
if (button) await button.click();
Использование .
в XPath запросе позволяет включать текст всех дочерних узлов, делая поиск более надежным и гибким.
Учтем пробелы и регистрозависимость
XPath в связке с функциями normalize-space()
и translate()
помогут справиться с излишними пробелами и разницей в регистрах:
const [button] = await page.$x("//button[contains(translate(normalize-space(.), 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'), 'текст кнопки')]");
if (button) await button.click();
Такой подход позволяет кликнуть по кнопке, не заботясь о регистрах букв и наличии пробелов.
Отказываемся от XPath в пользу селекторов с текстовым префиксом
С версии Puppeteer 18.0.0 стало возможным применять текстовые селекторы, которые могут быть проще XPath:
await page.click('text/Текст кнопки');
Текстовые селекторы идеально подходят для клика по невложенным текстовым элементам.
Управляем динамическим содержимым
Благодаря методам waitForXPath()
и waitForFunction()
, Puppeteer без проблем позволит дождаться появления элементов в динамичных веб-приложениях:
await page.waitForXPath("//button[contains(text(), 'Загрузить еще')]");
const [loadMoreButton] = await page.$x("//button[contains(text(), 'Загрузить еще')]");
if (loadMoreButton) await loadMoreButton.click();
Для ожидания конкретного текста можно использовать:
await page.waitForFunction(
text => document.body.innerText.includes(text),
{},
'Текст кнопки'
);
await page.click('button:contains("Текст кнопки")');
Следим за кавычками: продвинутый уровень
Если в текстах присутствуют кавычки, корректно их экранируйте:
const [button] = await page.$x("//button[contains(text(), \"Бургеры Боба\")]");
if (button) await button.click();
Используем CSS-селекторы с jQuery
Если в документе присутствует jQuery, можно использовать псевдоселектор :contains()
:
await page.click('button:contains("Возобновить")');
Визуализация
Вообразите Puppeteer как роботизированную руку, которая выбирает и нажимает кнопки на управляющей панели, усеянной различными надписями:
Панель управления (🎛️): [Старт ⏵, Стоп ⏹, Пауза ⏸, Возобновить ▶️]
Ее функция:
await page.click('button:contains("Возобновить")'); // 🤖 роботизированная рука тянется к кнопке "Возобновить ▶️"
Представление визуальной схемы:
🤖: [Ищу "Возобновить"...]
До: [⏵, ⏹, ⏸, ▶️]
После: *Клик* на [⏵, ⏹, ⏸, **👆▶️**]
Надежное взаимодействие с элементами
Для более надежного взаимодействия с элементами иногда следует преобразовать NodeList в массив или использовать document.evaluate
:
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. - Для повышения точности ваших селекторов добавляйте классы родительских элементов, чтобы исключить неправильные клики по повторяющимся в тексте элементам.
Полезные материалы
- GitHub – puppeteer/puppeteer: Node.js API для Chrome — официальный репозиторий Puppeteer с полным списком API.
- Puppeteer | Puppeteer – page.click() функция — официальная документация Puppeteer на функцию
page.click()
. - XPath | MDN — документация MDN Web, описывающая XPath и нужные для выбора элементов с уникальным текстом.
- Руководство по CSS-селекторам — полное руководство по CSS-селекторам, используемым для выбора элементов в Puppeteer.
- Обучающее видео по работе с Puppeteer — YouTube урок по управлению веб-элементами с помощью Puppeteer.
- Puppeteer | Puppeteer – page.evaluate() метод — подробности о методе
page.evaluate()
, критически важном для доступа к DOM и манипулирования элементами в Puppeteer. - Just a moment... – Обсуждение на Stack Overflow по клику на элементе с использованием Puppeteer — глубокое обсуждение на Stack Overflow, помогающее в реализации задач.