当前位置: 首页 > 后端技术 > Node.js

nodeJs爬虫路上的技术要点

时间:2023-04-03 20:19:37 Node.js

背景最近打算复习一下之前看过的nodeJs相关的内容,写几个爬虫解闷。爬取过程中发现了一些问题记录下来备忘。它依赖网上的cheerio库对爬取的内容进行处理,使用superagent处理请求,log4js记录日志。日志配置不多说,直接上代码:constlog4js=require('log4js');log4js.configure({appenders:{cheese:{type:'dateFile',filename:'cheese.log',pattern:'-yyyy-MM-dd.log',//包含模型alwaysIncludePattern:true,maxLogSize:1024,backups:3}},categories:{default:{appenders:['cheese'],level:'info'}}});constlogger=log4js.getLogger('cheese');logger.level='INFO';module.exports=logger;上面直接导出一个logger对象,在业务文件中直接调用logger.info()等函数添加日志信息即可,每天都会产生日志。网上有很多相关的资料。抓取内容并处理superagent.get(cityItemUrl).end((err,res)=>{if(err){returnconsole.error(err);}const$=cheerio.load(res.text);//解析当前页面并获取当前页面的城市链接地址constcityInfoEle=$('.newslist1lia');cityInfoEle.each((idx,element)=>{const$element=$(element);constsceneURL=$element.attr('href');//页面地址constsceneName=$element.attr('title');//城市名称if(!sceneName){return;}logger.info(`当前解析的目的地是:${sceneName},对应地址为:${sceneURL}`);getDesInfos(sceneURL,sceneName);//获取详细的城市信息ep.after('getDirInfoComplete',cityInfoEle.length,(dirInfos)=>{constcontent=JSON.parse(fs.readFileSync(path.join(__dirname,'./imgs.json')));dirInfos.forEach((element)=>{logger.info(`这个数据是:${JSON.stringify(元素)}`);Object.assign(content,element);});fs.writeFileSync(path.join(__dirname,'./imgs.json'),JSON.stringify(内容));});});});使用superagent请求页面,请求成功后使用cheerio加载页面内容,然后使用类似Jquery的匹配规则查找目标资源加载多个资源并使用eventproxy代理事件,处理事件的资源惩罚,在触发所有事件后处理数据。以上就是最基本的爬虫,接下来还有一些可能会出错或者需要特别注意的地方。..读写本地文件创建文件夹functionmkdirSync(dirname){if(fs.existsSync(dirname)){returntrue;}if(mkdirSync(path.dirname(dirname))){fs.mkdirSync(dirname);返回真;}返回假;}读写文件constcontent=JSON.parse(fs.readFileSync(path.join(__dirname,'./dir.json')));dirInfos.forEach((element)=>{logger.info(`这个数据是:${JSON.stringify(element)}`);Object.assign(content,element);});fs.writeFileSync(path.join(__dirname,'./dir.json'),JSON.stringify(content));批量下载资源下载的资源可能包括图片、音频等。使用Bagpipe处理异步并发参考constBagpipe=require('bagpipe');常量风笛=新风笛(10);bagpipe.push(downloadImage,url,dstpath,(err,data)=>{if(err){console.log(err);return;}console.log(`[${dstpath}]:${data}`);});下载资源,使用stream完成文件写入。functiondownloadImage(src,dest,callback){request.head(src,(err,res,body)=>{if(src&&src.indexOf('http')>-1||src.indexOf('https')>-1){request(src).pipe(fs.createWriteStream(dest)).on('close',()=>{callback(null,dest);});}});}编码有时直接使用cheerio.load处理网页内容。写入文件后,发现是经过编码的文本。你可以通过const$=cheerio.load(buf,{decodeEntities:false});禁止编码,ps:编码库和iconv-Lite无法将utf-8编码的字符转换成中文,可能是对API还不熟悉,以后可以关注一下。最后,附加一个匹配所有dom标签的常规constreg=/<.*?>/g;