从segmentfault爬数据到 用koa2,vue全家桶,mongodb开发一个segmentfault

前言

线上环境小包总

《从segmentfault爬数据到 用koa2,vue全家桶,mongodb开发一个segmentfault》

技术栈

  • 服务器: node、koa2
  • 客户端: vue、vuex、vue-router、Element-UI
  • 数据库: redis、mongodb
  • 打包: webpack

网站模块

  1. 爬虫模块:用于爬取一些我看的上的文章,主要采用request,cheerio模块对数据的爬取和处理,

    同时需要注意处理爬取图片的处理
  2. 文章模块:展示爬取的文章数据,并进行分类处理和展示
  3. 登录注册模块: 支持用户的登录注册,接入第三方登录接口,注册采用nodemailer模块进行邮箱验证
  4. 留言模块: 让用户在本网站留下自己的足记
  5. 统计模块: 统计网站访问量等数据

爬虫模块

segmentfault的文章不用登录就能查看,所有可用访问url就能取到文章的内容,唯一需要的注意的是请求的图片链接要做特殊的处理,最开始本来我是用的盗链的形式,后面过了一段时间segmentfault不允许盗链了,没办法只能从自己网站加载了。

在segmentfault中图片的src中带有?,&符号这中特殊的符号(应该是图片服务器的原因),并且也没有图片的后缀
<img data-src="/img/bVTrwb?w=598&h=122" src="/img/bVTrwb?w=598&h=122" style="cursor: pointer; display: inline;">
、所以我在爬取图片的时候就需要处理特殊符号,和加后缀

let imgError = false, imgPath = (imgSavePath + src).replace(/\?|\&/g, '_');
//替换特殊符号
let writeFile = fs.createWriteStream(imgPath), extname;
    request(_src || (addr + src), {timeout: 60000}).on('response', function(response){
        if(response.statusCode.toString().indexOf('4') == 0){
            self.remove();
            imgError = true;
            resolve2();
            return;
        }
        extname = path.extname(response.request.path);
        //在响应头中获取文件后缀                                
        if(!extname && response.headers['content-type'].indexOf('image') != -1){
            extname = '.' + response.headers['content-type'].split('/')[1];
            if(extname.indexOf('svg') != -1){
                extname = '.svg';
            }
        }
        let imgSrc = _src ?  src : src + extname;
        self.attr('src', imgSrc);
    }).on('error', function(err){
        writeLog('请求图片失败: '+ (_src||src)+ ' 来至url: '+ url, true);
        self.remove();
        imgError = true;
        reject2();
    }).pipe(writeFile);
    writeFile.on('finish', function(){
        if(imgError){
            return ;
        }    
        if(extname){
            let imgPath = (imgSavePath + src).replace(/\?|\&/g, '_');
            //添加后缀
            if(fs.existsSync(imgPath)){
                try{
                    if(src.indexOf('.') != -1){
                        resolve2('自带后缀: '+ src);
                        return;
                    }
                    fs.renameSync(imgPath, imgPath + extname);
                    writeLog('修改图片: ' + imgPath + extname);                            
                }catch(e){
                    writeLog('修图图片失败原因: .'+ src + extname + '\n' + e, true);
                }
                resolve2(imgPath + extname);
            }else {
                writeLog('图片不存在: .'+ src+ ' 来至url: '+ url, true);
                reject2(url);
            }
        }
    });

文章中的代码样式,需要自己用highlight模块去添加。
然后就是把文章的关键信息,如文件的url,时间,作者,保存到数据库,把文章的真正的html保存为一个文件,然后根据url去加载本地的html。

注意

  • 网站中用的所有技术可以交流学习
  • 不要以线上环境运行,因为源码中没有包含https相关文件
  • config.js中的github,qq授权登陆需要自己配置
  • mongodb账号密码只有读取权限

QQ交流群

133240225、 193572405
    原文作者:嘻倪孢
    原文地址: https://segmentfault.com/a/1190000010807252
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞