Снимок экрана для каждого узла DOM

Как я могу создавать скриншоты для каждого узла DOM на любом сайте?

Я пытался использовать безголовый браузер (кукловод), и он работает только тогда, когда я знаю XPath или Selector какого-либо элемента. Но как мне получить XPath или Selector для всех элементов?

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

Также я попытался использовать HtmlAgilityPack (C#) и перечислить каждый узел в HtmlDocument с помощью XPath, но этот XPath не может работать с puppeteer

Мне нужно использовать кукловод, потому что это лучший инструмент для создания скриншотов с помощью XPath или Selector.

Кто может мне помочь?

Ваш вопрос очень низкого качества, какую библиотеку вы используете? Что такое page? Я хочу помочь, но чувствую, что не могу, потому что мне не хватает информации. Если page.evaluate проходит через каждый элемент, почему бы не page.screenshot внутри него?

Tvde1 14.11.2018 09:09

@ Tvde1 может быть. Страница - это любая веб-страница во всемирной паутине. Вам нужно попытаться создать цикл page.evaluate и вызвать для него снимок экрана. Это распространенная и нерешенная проблема (сделайте снимок экрана для каждого доступного элемента на любой веб-странице). В последний раз я пытался получить для нее результат. И последним моим шагом был безголовый браузер "кукловод". Пожалуйста, не уменьшайте количество спорных вопросов.

Марат Зимнуров 14.11.2018 10:01

Серьезно, что такое page? Как создать объект? Это строка HTML? Это из библиотеки?

Tvde1 14.11.2018 11:06
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
10
3
6 089
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

С кукольником вам больше не нужно использовать скриншот всей страницы, поскольку у него есть elementHandle.screenshot ([параметры]). Вот что вы можете сделать:

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.info(`couldnt take screenshot of element with index: ${i}. cause: `,  e)
  }
}
await browser.close();

Обратите внимание, что кукловод не может получить скриншоты для некоторых элементов, которые невидимы или закрыты другими элементами и т. д. В таком случае вам нужно поймать ошибку и двигаться дальше.

Не знаю, как это работает, но когда на странице много элементов, этот цикл остановится без ошибок, он просто чего-то подождет ...

Марат Зимнуров 16.11.2018 12:10

Попробуй исполнить для ютуба

Марат Зимнуров 16.11.2018 13:08

@ МаратЗимнуров Только попробовал - у меня работает на youtube. node count: 1695 successful: 1094 not visible: 601 other: 0. Не похоже, что проблема с кодом.

shkaper 16.11.2018 19:58

@ МаратЗимнуров Ну, это тот же код плюс немного логирования: gist.github.com/shkaper/5421a9135f26ab57d368ae8bb39dcd22

shkaper 21.11.2018 13:45

Я пробовал запустить ваш код, но в следующий момент он остановится: ibb.co/bTrRZq

Марат Зимнуров 21.11.2018 14:55

может быть нужно запустить его из powershell вместо cmd?

Марат Зимнуров 21.11.2018 14:55

Сложно сказать. Забежал на макинтоше. Попробуйте использовать другой селектор или переверните массив узлов и начните делать снимки экрана с последнего узла в массиве. Или попробуйте запустить кукольник в полном режиме с puppeteer.launch({headless: false}) и посмотреть, что происходит на странице. Или установите точки останова, запустите скрипт с флагом --inspect и выполните пошаговое выполнение. Возможностей бесчисленное множество.

shkaper 21.11.2018 15:21

как я понимаю, когда узел пытается выполнить снимок экрана, веб-страница останавливается, но когда я изменяю размер окна браузера, он сохраняет снимок экрана и включает следующий узел. Резюме: когда узел виден и может создать снимок экрана, хром не может этого сделать и просто останавливается, но когда пользователь переключает размер браузера, он может создать снимок экрана и продолжить. магия. Я могу создать видео, если тебе нужно

Марат Зимнуров 21.11.2018 16:01

@ МаратЗимнуров Это действительно любопытно. Однако я думаю, что проблема, которую вы описываете, заслуживает отдельного вопроса.

shkaper 21.11.2018 16:16

также навигация между вкладками может избежать сна и создать снимок экрана. После того, как вы запустили его на Mac, у вас есть 1094 снимка экрана?

Марат Зимнуров 21.11.2018 18:26

пожалуйста, проверьте мой ответ ниже

Марат Зимнуров 21.11.2018 21:03

Другие вопросы по теме