除了img、input等标签会涉及图片资源外,对CSS样式表图片资源进行提取也是图片资源采集的重要议题。
1、CSS样式表分类
在一个页面中,对CSS样式表静态资源的应用主要分为:Inline,External ,Internal 三种。
1.1、Internal CSS
<style type="text/css"> body { background-color: blue; background-image: url("/1.png"); } </style>
1.2、External CSS
<link rel="stylesheet" type="text/css" href="style.css" />
1.3、Inline CSS
<body style="background-color:black;">
2、window.getComputedStyle
以上三种样式表可以算作静态样式表,在页面展示时候,浏览器Javascript引擎会针对每一个标签元素,计算应用在元素上的所有CSS属性对象。
因此要获取实际页面显示是否,某个标签对应的CSS,可以用 window.getComputedStyle(element) 来获得。
3、获取当前页面CSS样式表的图片元素
那么怎样获取当前页面所有标签元素的CSS样式表的图片资源?
由于样式表可能应用于当前页面的所有html标签元素上,如果对当前页面的所有标签元素都调用 window.getComputedStyle 计算一遍,以获取CSS样式中包含的图片资源,性能太差,用户等待时间过长。
思路:对img、input、button等标签元素,由于会逐个判断是否包含图片资源,因此可以同时window.getComputedStyle;对div、html、head、body等其他元素,可以只调用getComputedStyle。其他元素,直接解析静态资源样式表。
优化算法:
1)、筛选出可能包含图片的标签,判断src、href等属性是否包含图片资源,同时调用window.getComputedStyle。这样可以在一个循环中完成
let elements=document.querySelectorAll("img, input,button,iframe,source,svg,object,embed"); for (let element of elements) //let urls = await this.extractImageFromElement(element); //let url = await this.extractImagesFromComputedStyle(element); }
2)、对html,head,body,div几个标签元素,调用window.getComputedStyle
let elements=document.querySelectorAll("html,head,body,div"); for (let element of elements) //let url = await this.extractImagesFromComputedStyle(element); }
3)、对其他标签元素直接解析CSS静态资源
对Internal CSS,可以 document.getElementsByTagName(“style”);
对External CSS,可以通过 document.styleSheets 获得
Scraper.prototype.extractImagesFromStyles = async function (content) { let imagesFromStyles = []; try { let myDocument = document.implementation.createHTMLDocument(""); myDocument.open(); myDocument.write(content); myDocument.close(); //inline stylesheet tags let styles = myDocument.getElementsByTagName("style"); for (let style of styles) { let cssRules = style.sheet.cssRules || style.sheet.rules; for (let j = 0; j < cssRules.length; j++) { const style = cssRules[j].style; if (style && style.backgroundImage) { let href = this.extractURLFromStyle(style.backgroundImage); if (!["initial", "none", "inherit"].includes(href)) { let url = this.relativeUrlToAbsolute(href); try { let info = await this.getImageInfo(url); if (info && info.mime) { imagesFromStyles.push(url); } } catch (err) {} } } } } //link stylesheets for (let styleSheet of myDocument.styleSheets) { cssRules = styleSheet.cssRules || styleSheet.rules; for (let j = 0; j < cssRules.length; j++) { style = cssRules[j].style; if (style && style.backgroundImage) { let href = this.extractURLFromStyle(style.backgroundImage); let url = this.relativeUrlToAbsolute(href); try { let info = await this.getImageInfo(url); if (info && info.mime) { imagesFromStyles.push(url); } } catch (err) {} } } } } catch (err) { console.debug("extractImagesFromStyles err is:" + JSON.stringify(err, Object.getOwnPropertyNames(err), 2)); } console.debug("extractImagesFromStyles 3 is:" + JSON.stringify(imagesFromStyles)); return imagesFromStyles; };
转载请注明:出家如初,成佛有余 » 一键转贴Chrome扩展开发经验总结7:CSS图片提取