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



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


С кукольником вам больше не нужно использовать скриншот всей страницы, поскольку у него есть 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();
Обратите внимание, что кукловод не может получить скриншоты для некоторых элементов, которые невидимы или закрыты другими элементами и т. д. В таком случае вам нужно поймать ошибку и двигаться дальше.
Не знаю, как это работает, но когда на странице много элементов, этот цикл остановится без ошибок, он просто чего-то подождет ...
Попробуй исполнить для ютуба
@ МаратЗимнуров Только попробовал - у меня работает на youtube. node count: 1695 successful: 1094 not visible: 601 other: 0. Не похоже, что проблема с кодом.
@ МаратЗимнуров Ну, это тот же код плюс немного логирования: gist.github.com/shkaper/5421a9135f26ab57d368ae8bb39dcd22
Я пробовал запустить ваш код, но в следующий момент он остановится: ibb.co/bTrRZq
может быть нужно запустить его из powershell вместо cmd?
Сложно сказать. Забежал на макинтоше. Попробуйте использовать другой селектор или переверните массив узлов и начните делать снимки экрана с последнего узла в массиве. Или попробуйте запустить кукольник в полном режиме с puppeteer.launch({headless: false}) и посмотреть, что происходит на странице. Или установите точки останова, запустите скрипт с флагом --inspect и выполните пошаговое выполнение. Возможностей бесчисленное множество.
как я понимаю, когда узел пытается выполнить снимок экрана, веб-страница останавливается, но когда я изменяю размер окна браузера, он сохраняет снимок экрана и включает следующий узел. Резюме: когда узел виден и может создать снимок экрана, хром не может этого сделать и просто останавливается, но когда пользователь переключает размер браузера, он может создать снимок экрана и продолжить. магия. Я могу создать видео, если тебе нужно
@ МаратЗимнуров Это действительно любопытно. Однако я думаю, что проблема, которую вы описываете, заслуживает отдельного вопроса.
также навигация между вкладками может избежать сна и создать снимок экрана. После того, как вы запустили его на Mac, у вас есть 1094 снимка экрана?
пожалуйста, проверьте мой ответ ниже
Ваш вопрос очень низкого качества, какую библиотеку вы используете? Что такое
page? Я хочу помочь, но чувствую, что не могу, потому что мне не хватает информации. Еслиpage.evaluateпроходит через каждый элемент, почему бы неpage.screenshotвнутри него?