Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Screenshot for each DOM node

How can I create screenshots for every DOM node in any site?

I tried to use headless browser (puppeteer) and it's working only when I know XPath or Selector of some element. But how to I can receive XPath or Selector for all elements?

async function screenshotDOMElement(opts = {}) {
const padding = 'padding' in opts ? opts.padding : 0;
const path = 'path' in opts ? opts.path : null;
const selector = opts.selector;

if (!selector)
    throw Error('Please provide a selector.');

const rect = await page.evaluate(selector => {
    const element =
     document.evaluate(selector, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
    if (!element)
        return null;
    const {x, y, width, height} = element.getBoundingClientRect();
    console.log (x,y,width,height)
    return {left: x, top: y, width, height, id: element.id};
}, selector);

if (!rect)
    throw Error(`Could not find element that matches selector: ${selector}.`);

return await page.screenshot({
    path,
    clip: {
        x: rect.left - padding,
        y: rect.top - padding,
        width: rect.width + padding * 2,
        height: rect.height + padding * 2
    }
});
}

Also I tried to use HtmlAgilityPack (C#) and enumerate each node in HtmlDocument by XPath, but this XPath can't work with puppeteer

I need to use puppeteer 'cos it's the best instrument for screenshot-task by XPath or Selector

Who can help me?

like image 713
Марат Зимнуров Avatar asked Nov 11 '18 19:11

Марат Зимнуров


People also ask

How do you capture a dom?

Inspect the DOM element to highlight it in the Elements panel of the DevTools. Press Cmd/Ctrl+Shift+P to pull up the DevTools command palette (also something new I just learned about!) Choose “Capture node screenshot” Save the file.

How do you screenshot on Inspect Element?

Inspect the element you wish to capture. Open the Command Menu with Cmd + Shift + P / Ctrl + Shift + P. Type in screenshot within the Command Menu. You can now capture the screenshot of only the specific element, a viewport screenshot, or a full-page screenshot.

What is screenshot node?

Takes a screenshot of selected area and saves it to disk.

How do you screenshot on a element puppeteer?

Puppeteer Screenshot to Take Screenshot of an Element Simply copy the selector of an element by right-clicking on the element and selecting Inspect. Then, right-click the highlighted part and select Copy and Copy Selector.


1 Answers

With puppeteer, you don't need to use the whole page screenshot anymore, since it has elementHandle.screenshot([options]). Here's what you can do:

const browser = await puppeteer.launch();

const page = await browser.newPage();
await page.goto('https://example.com');

// get a list of all elements - same as document.querySelectorAll('*')
const elements = await page.$$('*')

for (let i = 0; i < elements.length; i++) {
  try {
    // get screenshot of a particular element
    await elements[i].screenshot({path: `${i}.png`})
  } catch(e) {
    // if element is 'not visible', spit out error and continue
    console.log(`couldnt take screenshot of element with index: ${i}. cause: `,  e)
  }
}
await browser.close();

Notice than puppeteer fails to get screenshots for some elements that are invisible or covered by other elements, etc. In such a case, you need to catch an error and move on.

like image 103
shkaper Avatar answered Oct 17 '22 13:10

shkaper