How to extract text content from elements using Puppeteer

I’m working with Puppeteer and need to extract the text content from DOM elements. I also want to know if it’s possible to click on an element based on its text content.

Here’s what I’m trying to achieve with regular JavaScript:

let elementFound = false;
$('.my-selector').each(function() {
    if (elementFound) return;
    const cleanText = $(this).html().replace(/\D/g, '');
    if (cleanText === '10') {
        $(this).click();
        elementFound = true;
    }
});

Can someone help me figure out how to do something similar in Puppeteer? I need to grab the inner content of elements and potentially interact with them based on that content.

you could also try page.$eval() with textContent instead of innerHTML. Something like const text = await page.$eval('.my-selector', el => el.textContent.replace(/\D/g, '')); then check if it matches what you need. for clicking based on text content, xpath’s your best bet: await page.$x("//div[contains(@class,'my-selector') and contains(text(),'10')]") then click the element it returns.

Use page.evaluate() to run JavaScript directly in the browser context. Here’s how I handle this:

const elementClicked = await page.evaluate(() => {
    const elements = document.querySelectorAll('.my-selector');
    for (const element of elements) {
        const cleanText = element.innerHTML.replace(/\D/g, '');
        if (cleanText === '10') {
            element.click();
            return true;
        }
    }
    return false;
});

You can also extract text content first, then click based on conditions outside the evaluate function. I’ve had good luck with page.$$eval() for grabbing text from multiple elements, then using XPath selectors with page.$x() to click elements with specific text. Just remember that Puppeteer operations need to be wrapped in evaluate functions to run in the browser context.

I’ve found page.$$eval() really handy for this since it grabs elements and extracts content in one go. Extract all the text first, then handle clicking separately:

const textContents = await page.$$eval('.my-selector', elements => 
    elements.map(el => el.innerHTML.replace(/\D/g, ''))
);

const targetIndex = textContents.findIndex(text => text === '10');
if (targetIndex !== -1) {
    await page.click(`.my-selector:nth-child(${targetIndex + 1})`);
}

Separating text extraction from clicking makes debugging way easier. I’ve hit timing issues cramming everything into one evaluate function, especially with dynamic content that loads after the page renders.