How to click a link containing specific content from a puppeteer?

If I have content on my page, such as:

<a>Hi!</a> 

How can I use Google Puppeteer to automate clicking this item?

I need to be able to select it based only on its contents, not an identifier, class, or attribute.

Is there something like $('a:contains("Hi!")') That I can use to select this element?

How can I do this with https://github.com/GoogleChrome/puppeteer

thanks

+6
css-selectors browser-automation puppeteer
source share
2 answers

First we need to find the element in the text.

 /** * 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'}); 

Save it in the same folder as your puppeteer script, name it script.js .

Now we can use this in our puppeteer script. We can use the ElementHandle, but for ease of understanding, I use the .evaluate() function provided by the puppeteer.

 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(); })(); 

Do not copy paste the code above, try to understand it and enter it yourself. If the code above does not work, try to find out why it does not work.

+4
source share

Alternative approach using XPath

There is a much simpler way to do this using the XPath expression:

 const aElementsWithHi = await page.$x("//a[contains(., 'Hi!')]"); await aElementsWithHi[0].click(); 

Using page.$x , this code finds all the elements with the text a Hi! inside. The result will be an array containing the matching handle element. a Using the elementHandle.click function, we can then click on the element.

0
source share

All Articles