分享一个自动爬取静态站的工具

分享一个自动爬取静态站的工具

点点

2021-03-28 20:47 阅读 283 喜欢 0

资源

抓取页面最主要的还是页面中涉及到的资源,将资源主要分为以下几个:

css文件 js文件 页面引入的图片 css引入的图片 页面做的背景图

规则

在抓取资源的时候也不是所有都抓取,有些网站引入的是cdn或者外部的资源文件,这类的就不准备抓取了,直接使用,还有些图片跟站点的域名不同,也需要将host添加进来,防止图片不再下载。

因此,做了以下几个变量:

//定义几个资源的前置路径,可以为空 //*** CSS 文件的路径前缀 let cssprefix = '/static/css/', //=== 图片文件的路径前缀 imgprefix = '/static/image/', //=== js文件的路径前缀 jsprefix = '/static/js/', //=== css文件中的使用的背景图片相对于css文件的相对路径. cssimgprefix = '../image/'; //抓取目标内容 let targetUrl = http://xxx.html, targetFolderName = 宝翔电商; let targetHost = ['www.xxx.com','hz.xxx.com']; let pageCode = 'utf8';//页面编码,默认utf8,有些页面是gbk. let deepFetch = false;//是否深度抓取,false则只抓取当前页面,true则从当前页面进行继续抓取。 let staticDomain = []; 定义好存储目录以及对应的host和编码,就可以开始了,给定一个入口路径,从该页面开始抓取A标签,进行挨个获取和存储。

核心代码

代码很简单,就是获取html代码后进行img css 内容解析就OK了,然后做个循环,依次抓取。

//流程: /**

//初始创建文件夹 if(!fs.existsSync(folderPath)){ fs.mkdirSync(folderPath); // fs.mkdirSync(path.join(folderPath,'css')) // fs.mkdirSync(path.join(folderPath,'js')) // fs.mkdirSync(path.join(folderPath,'img')) // fs.mkdirSync(path.join(folderPath,'bg')) }

; //做循环处理 var urlMap = {};//做去重处理。

(async function(){ while(pageUrlArr.length > 0){ //每次都是第一个 var currentUrl = pageUrlArr.splice(0,1)[0]; console.log(开始抓取页面:${currentUrl}) //对href进行甄别处理。 var fileNameObj = tool.getFileName(currentUrl); if(targetHost.indexOf(fileNameObj.host) > -1){//不是本站数据,忽略。 //获取html let htmlContent = await tool.fetch(currentUrl); //如果无法访问则忽略 if(htmlContent != ''){ //加入判断map let ccodeurl = encodeURIComponent(currentUrl); urlMap[ccodeurl] = fileNameObj.fileName;//加入map,防止重复下载 //对内容进行解析,获得地址信息。 let $ = cheerio.load(htmlContent); //检索所有的相关数据以及图片等 const $a = $('a');//所有的a标签,并进行记录判断 console.log(获得A标签:${$a.length}) $a.each(function(index,item){ var ahref = $(item).attr('href'); if(ahref && ahref.indexOf('javascript') < 0 && ahref.indexOf('void') < 0){//存在且不是js函数 // var ahrefobj = url.parse(ahref); let realHref = ahref; //如果不是hostname if(tool.shouldDown(ahrefobj)){//引入的其他的站点地址 if(ahrefobj.host == null){ realHref = new URL(ahref,currentUrl).href; } //并进行替换。 var fileInfo = tool.getFileName(realHref); //此处替换需要通过正则进行替换 let regexp = new RegExp('"('+ahref+')"','g'); htmlContent = htmlContent.replace(regexp,'"'+fileInfo.fileName+'"'); let acodeurl = encodeURIComponent(realHref); if(!urlMap[acodeurl] && deepFetch){ urlMap[acodeurl] = fileInfo.fileName; pageUrlArr.push(realHref); } } } })

            //js文件
            const $script = $('script').get();
            console.log(`获得js文件:${$script.length}`)
            for(let i in $script){
                let item = $script[i];
                let shref = $(item).attr('src');
                if(shref){
                    let shrefobj = url.parse(shref);
                    let realHref = shref;
                    if(tool.shouldDown(shrefobj)){//相对路径
                        //进行下载。
                        if(shrefobj.host == null){
                            realHref = new URL(shref,currentUrl).href;
                        }
                        let fileInfo = tool.getFileName(realHref);
                        htmlContent = htmlContent.replace(shref,jsprefix+fileInfo.fileName)
                        await tool.download(path.join(folderPath,jsprefix,fileInfo.fileName),realHref);
                    }
                }
            }

            //css文件
            const $css = $('link').get();
            console.log(`获得css文件:${$css.length}`)
            for(let i in $css){
                let item = $css[i];
                let chref = $(item).attr('href');
                if(chref){
                    let realHref = chref;
                    let chrefobj = url.parse(chref);
                    if(tool.shouldDown(chrefobj)){//相对路径
                        //进行下载。
                        if(chrefobj.host == null){
                            realHref = new URL(chref,currentUrl).href;
                        }
                        let fileInfo = tool.getFileName(realHref);
                        htmlContent = htmlContent.replace(chref,cssprefix+fileInfo.fileName)
                        let cssContent = '';
                        try{
                            cssContent = await tool.fetch(realHref);
                        }catch(e){
                            console.log(`抓取失败:${e.message},${realHref}`)
                        }
                        //对css内容进行处理。
                        let cssarr = cssContent.match(/url\(([\s\S^]*?)\)/g);
                        if(cssarr && cssarr.length > 0){//存在
                            for(let m in cssarr){
                                let cssitem = cssarr[m];
                                let tempPath = (cssitem.match(/url\(([\s\S^]*?)\)/)[1]).trim();
                                tempPath = tempPath.replace(/"/g,'');
                                let cssbgreal = new URL(tempPath,realHref).href;
                                //下载
                                let cssbgInfo = tool.getFileName(cssbgreal);
                                cssContent = cssContent.replace(tempPath,cssimgprefix+cssbgInfo.fileName);
                                await tool.download(path.join(folderPath,imgprefix,cssbgInfo.fileName),cssbgreal);
                            }
                        }
                        //吸入
                        let tempCssPath = path.join(folderPath,cssprefix,fileInfo.fileName);
                        tool.mkdir(path.dirname(tempCssPath))
                        fs.writeFileSync(tempCssPath,cssContent);
                    }
                }
            }

            //img 文件
            const $img = $('img').get();
            console.log(`获得图片:${$img.length}`)
            for(let i in $img){
                let item = $img[i];
                let chref = $(item).attr('src');
                //由于
                if(imgAttr!='' && $(item).attr(imgAttr) != undefined){
                    let dchref = $(item).attr(imgAttr);
                    let dchrefobj = url.parse(dchref);
                    let drealHref = dchref;
                    if(tool.shouldDown(dchrefobj)){//相对路径
                        //进行下载。
                        if(dchrefobj.host == null){
                            drealHref = new URL(dchref,currentUrl).href;
                        }
                        let dfileInfo = tool.getFileName(drealHref);
                        htmlContent = htmlContent.replace(dchref,imgprefix+dfileInfo.fileName);
                        await tool.download(path.join(folderPath,imgprefix,dfileInfo.fileName),drealHref);
                    }
                }
                if(chref){
                    let chrefobj = url.parse(chref);
                    let realHref = chref;
                    if(tool.shouldDown(chrefobj)){//相对路径
                        //进行下载。

                        if(chrefobj.host == null){
                            realHref = new URL(chref,currentUrl).href;
                        }
                        let fileInfo = tool.getFileName(realHref);
                        htmlContent = htmlContent.replace(chref,imgprefix+fileInfo.fileName);
                        await tool.download(path.join(folderPath,imgprefix,fileInfo.fileName),realHref);
                    }
                }
            }

            //处理最后的background-image 的写死样式问题
            let bgarr = htmlContent.match(/url\(([\s\S^]*?)\)/g);
            console.log(`处理css内引用文件`)
            if(bgarr && bgarr.length > 0){//存在
                for(let m in bgarr){
                    let bgitem = bgarr[m];
                    let tempPath = (bgitem.match(/url\(([\s\S^]*?)\)/)[1]).trim();
                    tempPath = tempPath.replace(/"/g,'');
                    let bgreal = new URL(tempPath,currentUrl).href;
                    //下载
                    let bgInfo = tool.getFileName(bgreal);
                    htmlContent = htmlContent.replace(tempPath,imgprefix+bgInfo.fileName);
                    await tool.download(path.join(folderPath,imgprefix,bgInfo.fileName),bgreal);
                }
            }

            //将html存储起来。
            let currentFilePath = path.join(folderPath,fileNameObj.fileName);
            tool.mkdir(path.dirname(currentFilePath));
            // htmlContent = htmlContent.replace(currentUrl,fileNameObj.fileName);
            fs.writeFileSync(currentFilePath,htmlContent);

        }
    }
}
console.log(`执行完毕----------------`)
process.exit(0);

})();

效果还不错与原网站一样,稍微改动下就换了个名。

转载请注明出处: http://sdxlp.cn/article/gongju.html


如果对你有用的话,请赏给作者一个馒头吧 ...或帮点下页面底部的广告,感谢!!

赞赏支持
提交评论
评论信息(请文明评论)
暂无评论,快来快来写想法...
推荐
QQ是80后的一代回忆,那个时候QQ可是通信的主要软件,不仅可以聊天还可以玩游戏,应该是很多小伙伴们的恋爱神器, QQ是腾讯QQ的简称,是腾讯公司推出的一款基于互联网的即时通信软件,QQ可以聊天,发动态等很多功能,那qq怎么看以前加过的好友呢,就让小编带小伙伴们来看一下吧。
作为微软比较稳的操作系统,越来越多小伙伴们都升级或重装了Windows10,不过也有部分小伙伴们遇到了一些比较棘手的问题,比如今天要分享的win10开机黑屏时间长,通常都是开机比较慢,然后是黑屏,用户需要等半分钟,甚至一分钟才能进入系统。那么,win10开机黑屏时间长怎么办?
需要公司的LOGO信息,但是没有,只有公司的名字,想着成个默认的,该怎么处理哪?看下边文章,可以学到经验啊!
在使用电脑的时候,相信小伙伴们都可能遇到过这种情况,那就是不小心安装了捆绑软件,或者中毒了等原因,导致电脑不停自动安装垃圾软件怎么办?那么这种情况该如何阻止电脑安装垃圾软件?下面点点就教小伙伴们阻止电脑安装垃圾软件的方法。
青少年玩游戏的很多,但大部分都是用家长的手机,玩游戏哪就免不了会充个会员啊!买个装备之类,这就需要钱了,微信的钱就会不知不觉的少掉,家长该怎么处理那?目前青少年模式需要更新微信ios最新版本7.0.17以上的版本才可以使用。
几个月前朋友发的图片,现在打开的时候,显示图片已过期,这个时候不要着急,跟点点来看看吧,教你一键恢复。
如果有台能翻墙的服务器,那么我们就可以自己做一个代理,这样本地就可以上网啦..
现在有很多企业都在使用钉钉办公,有些小伙伴嘛呢不知道电脑钉钉怎么设置OA审批人员,接下来小编就给小伙伴们介绍一下具体的操作步骤。