Как перейти по ссылке, которая содержит определенный контент в кукловоде?
Если у меня есть контент на моей странице, такой как:
<a>Hi!</a>
Как я могу использовать Google Puppeteer для автоматизации нажатия этого элемента?
Мне нужно иметь возможность выбрать его на основе только его содержимого, а не идентификатор, класс или атрибут.
Есть ли что-то вроде $('a:contains("Hi!")')
что я могу использовать, чтобы выбрать этот элемент?
Как я могу сделать это с помощью https://github.com/GoogleChrome/puppeteer
Спасибо
1 ответ
Сначала мы должны найти элемент за текстом.
/**
* findElemByText - Find an Element By Text
*
* @param {String} str case-insensitive string to search
* @param {String} selector = '*' selector to search
* @param {String} leaf = 'outerHTML' leaf of the element
* @return {Array} array of elements
*/
function findElemByText({str, selector = '*', leaf = 'outerHTML'}){
// generate regex from string
const regex = new RegExp(str, 'gmi');
// search the element for specific word
const matchOuterHTML = e => (regex.test(e[leaf]))
// array of elements
const elementArray = [...document.querySelectorAll(selector)];
// return filtered element list
return elementArray.filter(matchOuterHTML)
}
// usage
// findElemByText({str: 'Example', leaf: 'innerHTML', selector: 'title'});
// findElemByText({str: 'Example', selector: 'h1'});
// findElemByText({str: 'Example'});
Сохраните его в той же папке, что и ваш сценарий кукловода, назовите его script.js
,
Теперь мы можем использовать это в нашем сценарии кукловода. Мы можем использовать ElementHandle, но для простоты понимания я буду использовать .evaluate()
Функция обеспечена кукловодом.
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto('https://example.com');
// expose the function
await page.addScriptTag({path: 'script.js'});
// Find Element by Text and Click it
await page.evaluate(() => {
// click the first element
return findElemByText({str: 'More'})[0].click();
});
// Wait for navigation, Take Screenshot, Do other stuff
await page.screenshot({path: 'screenshot.png'});
await browser.close();
})();
Не копируйте и не вставляйте приведенный выше код, постарайтесь понять его и наберите их самостоятельно. Если приведенный выше код не работает, попробуйте найти причину сбоя.
Альтернативный подход с использованием XPath
Есть гораздо более простой способ сделать это с помощью выражения XPath:
const aElementsWithHi = await page.$x("//a[contains(., 'Hi!')]");
await aElementsWithHi[0].click();
С помощью page.$x
, этот код находит все a
элементы с текстом Hi!
внутри. Результатом будет массив, содержащий совпадающиеa
элемент ручки. Используя elementHandle.click
функции, затем мы можем щелкнуть элемент.