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

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

点点

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


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

赞赏支持
提交评论
评论信息(请文明评论)
暂无评论,快来快来写想法...
推荐
听到好微信的音频,该如何去下载?视频可以去腾讯视频里搜视频名字,可以找得到视频页面链接。音频有两种:音乐就直接去后台搜,如果是录音的那种音频,用以下方法下载。免费保证百分百成功。
生活中,微信是我们必备的软件,那么微信铃声主要在来新消息、语音/视频通话时提醒我们,可以通过设置来修改铃声,可以自定义铃声,或者使用官方提供的铃声,那具体怎么设置呢?下面就和点点一起来看看吧!
无线网,现在人们使用的越来越多了。很多小伙伴用的苹果设备,苹果设备间的操作是比较方便的,而且iPhone还可以给ipad共享wifi密码的哦,iphone怎么共享wifi给ipad呢?
一个服务号,是认证过了的,为了实现微信支付。 但是,去申请下微信登录的时候,发现,竟然还需要微信开放平台的开发者认证,而且认证得花钱...而且服务号的认证还不算...怎么办哪?
小伙伴们都说微信所占用的内存很多,其实微信本身并不会占用很多内存,占内存的其实是微信里面的文件,包括图片、视频、语音、聊天记录等。当我们不小心操作失误或卸载了微信时,微信里面的数据也会随之消失,如果要避免这种情况的话,建议小伙伴们还是将微信上的内容备份一下比较好。 微信聊天记录如何备份,教你一个方法特别简单又实用,跟小编来看看吧!
这几天很多小伙伴们私信点点,问点点这个问题,今天点点就给小伙伴们写了一篇关于安卓系统和苹果系统怎么查看微信撤回消息的文章,希望小伙伴们喜欢,不过好奇害死猫啊!要慎重的去看这个事情。
现在的社交软件有很多,但是实用面积广的就哪几个,里边QQ是最早的功能也是比较全的,QQ是现在十分常用的游戏社交软件之一,有些小伙伴不知道怎么找到手机中的QQ文件,接下来小编就给小伙伴们介绍一下具体的操作步骤。
智能手机现在人手一台,手机QQ是现在最常用的社交、办公软件之一,有些小伙伴们想知道手机QQ怎么查找历史文件,接下来小编就给小伙伴们介绍一下具体的操作步骤。