Есть ссылка на сайт. Необходимо получить 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 не предлагать. Не справляется.
Код тут :
https://github.com/Zimtir/NodeScreenshoter/
Оф. документация тут :
https://github.com/GoogleChrome/puppeteer/blob/v1.10.0/docs/api.md#elementhandlescreenshotoptions
Через селениум:
Сначала находим в нужной ноды размер и позицию:
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 раз, а дальше просто перебирать координаты и размеры нужных нод.
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
Приложение устанавливаться не будетНужна небольшая бд
Как отправить get запрос на определенный урл через прокси? Результат обрабатывать никак не надо, необходимо просто обратится к апи сервиса...
На данный вопрос уже ответили:
GridView отображает на странице данные из коллекции объектов: