#javascript #c_sharp #net #nodejs #веб_программирование
Есть ссылка на сайт.
Необходимо получить selector или xpath для всех доступных элементов.
К примеру, есть https://youtube.com
Если мы возьмем элемент по
//*[@id="meta"]/h3
То мы получим какой-либо объект и сможем например вызвать у него
getBoundingClientRect()
Тоже самое если брать селектор элемента
#meta > h3
По нему всё тоже нормально
Потому что элемент видим.
Как решить эту задачу?
Единственный вариант к которому пришел - это поднимать CefSharp и бегать через keyboard
control по Nodes в DevTools и получать xPath/selector нажатием правой кнопки мыши
Что пробовал :
HtmlAgilityPack (C#) подключался через web.load("youtube.com") и кормил его HtmlDocument
Но я получал NodeCollection, где xPath /html[1]/body[1]/div[1]
Почему такой вариант не подходит?
puppeteer не может сделать скриншот на основе этого элемента, не знаю почему, но
не может.
реализация нужна именно под puppeteer (он лучше всего справляется с созданием скриншота
на основе 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.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
}
});
}
Как получить скриншот всех элементов какого-либо сайта?
Selenium не предлагать. Не справляется.
Ответы
Ответ 1
Код тут : https://github.com/Zimtir/NodeScreenshoter/ Оф. документация тут : https://github.com/GoogleChrome/puppeteer/blob/v1.10.0/docs/api.md#elementhandlescreenshotoptionsОтвет 2
Через селениум: Сначала находим в нужной ноды размер и позицию: Size elemSize = Element.Size; Point point = Element.Location; Потом берем скриншот стандартными средствами селениума и обрезаем по уже снятых ранее параметрах Screenshot myScreenShot = ((ITakesScreenshot)Instance).GetScreenshot(); Bitmap screen = new Bitmap(new MemoryStream(myScreenShot.AsByteArray)); Bitmap nodeScreen = screen.Clone(new Rectangle(point, size), screen.PixelFormat); Собственно, дальше остается только сделать перебор всех нод и сделать скриншот. PhantomJS, на сколько я помню, делает скриншот ВСЕЙ страницы какого бы размера оне не была. Так что никаких костылей связанных с тем, что элемент не видно на странице не будет в случае его использования. Так же для оптимизации можно делать скриншот страницы только 1 раз, а дальше просто перебирать координаты и размеры нужных нод.
Комментариев нет:
Отправить комментарий