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

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

点点

2021-03-28 20:47 阅读 288 喜欢 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


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

赞赏支持
提交评论
评论信息(请文明评论)
暂无评论,快来快来写想法...
推荐
我们日常必备的聊天工具微信,在使用的时候也有误删人的情况出现,这个时候小伙伴们知道怎么悄悄的将删除的人加回来呢?最快将删除的人加回来的方法有哪些呢?
一直在做K12教育方面的产品,不过大都是学校管理层面的,对于教学一直很少触及。当然,这类的产品已经存在不少了,在功能、设计方面我们都会借鉴一些进行改进,其中有一些基础数据.需要的话,看文章低端。
前几天出了一起qq闪照的破解方法,不想因为当天的点击率到了2万加,被不怀好意的朋友给举报啦!呵呵,有的小伙伴在评论下留言需要制作的方法,那么今天它来了。
腾讯微信的拍一拍具有非常好玩的功能,可以双击对方的头像,显示出非常可爱的拍一拍后缀,所以很多小伙伴们想要知道微信拍拍功能怎么给自己加文字,这样就会显示出好玩的后缀文字,下面就让小编给小伙伴们介绍一下微信拍拍功能给自己加文字教程。
在日常生活工作中,我们使用微信聊天的时候,经常会遇到各种想要分享的聊天记录,对于很多用户来说,把聊天记录还有照片都转发给好友,所以想要知道微信怎么转发别人的图片和文字,下面就让小编给小伙伴们介绍一下微信转发别人的图片和文字教程。
现在的智能手机系统一般分为苹果系统与安卓系统,安卓系统的内存本来就比较少,安卓生态较为混乱,开发人员技术水平参差不齐,安卓手机的目录总是很混乱。有些像小编一样有强迫症的人就喜欢清理一些没用的文件或文件夹,还自己手机一点内存。最好是有点底子小伙伴使用呦,如果看不到建议使用手机自带的清理软件。
现在很多小伙伴使用手机都会安装微信,可以用来社交聊天,还可以转账提现,最近有小伙伴在询问财产提现很久没有到账,怎么才能解决,那么点点在这里分享一下微信提现未到账解决方法,有需要的小伙伴,可以看看哦!小知识解决大问题!
微信dat文件是在PC端微信软件产生的图片文件,对,这个文件实际上是一个图片,微信将聊天过程中产生的图片进行异或加密,更改了后缀存储为dat文件。 所以实际上,dat文件在微信软件中99%的都是图片,剩余一小部分是配置文件。