#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 раз, а дальше просто перебирать координаты и размеры нужных нод.
Комментариев нет:
Отправить комментарий