I’m curious about how these two snippets of code differ in functionality.
const buyLink = await page.$('a.buy-button');
const url = await buyLink.getProperty('href');
await buyLink.click();
await page.evaluate(() => {
const buyLink = document.querySelector('a.buy-button');
const linkUrl = buyLink.href;
buyLink.click();
});
In my experience, working directly with raw DOM elements inside page.evaluate() seems simpler, while the ElementHandles from the $ functions appear overly abstracted. I wonder if the async methods provided by Puppeteer might offer better performance or enhance dependability? There’s a lack of clear guidance on this in the documentation, so I’m eager to grasp the advantages and disadvantages of each method, as well as the reasoning for introducing functions like page.$$().
In addition to what’s been mentioned, an aspect worth considering is the security context. With page.evaluate(), the JavaScript executed is limited to the page’s context, avoiding any node.js functionality, which inherently adds a security layer by limiting potential vulnerabilities. For scenarios requiring complex interactions or when handling dynamic content that might reload, Puppeteer’s $ functions might offer more consistency as the usual async nature of puppeteer can handle changes better than relying solely on direct DOM interactions through evaluate.
Hey Dave! both approaches have their place. with $, you deal with puppeteer’s ElementHandle, allowing direct async ops like click(). evaluate() runs JS within the page context, interacting directly with the DOM. $ can be safer as it avoids potent’ial page-reloading issues during script execution. choose based on task needs!