nodejs 爬取小说
2018-03-11 20:28
141 查看
前言
前段时间看到有个同学用python爬取了小说,于是打算用nodejs爬取一下小说,在这里先总结一下整个过程.(仅供学习,请勿商业)效果图
爬取思路
爬取首页url,然后把所有要爬取的url放在数组,准备爬取大概有2300多个url要爬取,不可能一下发出2000多条请求,这样请求失败可能性极大.我使用了async这个包,控制了一下并发,请求控制为5,效果还是挺好的.设置代理,再提高一下并发数的话,效率就可以大大提高了.
使用到的npm包
request 用来发送请求,可以用superagent代替iconv-lite 用来转码
cheerio 类似Jquery的一个库,方便dom操作
async 控制并发数
具体代码
// request const request = require('request'); const iconv = require('iconv-lite'); // 类似jquery的一个库 const cheerio = require('cheerio'); // 文件管理模块 const fs = require('fs'); // 控制并发数 const async = require('async'); var URL = 'http://www.biquge.com.tw/3_3711/'; var NUMBER = 0; var start = new Date(); console.log("开始爬取首页......"); var Options = { method: 'GET', encoding: null, url:URL, timeout:100000 }; request(Options,function(err,res,body){ if(err){ console.log('首页爬取失败'); console.log(err); return ; } console.log("首页爬取成功,费时" + (new Date() - start) / 1000 + '秒'); // 处理爬取的信息 body = iconv.decode(body,'gbk'); var $ = cheerio.load(body); var MAXLIMIT = 5; var TITLE = $('#info>h1').text() + '.txt'; var urls = $('#list>dl>dd>a'); var URLS = []; urls.each( function(index,ele){ var a = $(this); var url = URL.substring(0,25) + a.attr('href'); var data = { 'index':index, 'url':url, 'title':a.text() }; URLS.push(data); }); async.mapLimit(URLS,MAXLIMIT,function(item,callback){ getData(item,callback) },function(err,result){ var end = ( new Date() - start ) /1000; console.log(`爬取所有信息费时${end}秒`); result.sort(function(a,b){ return a.index - b.index; }); result = result.map(function(item){ return item.title + '\n\r' + item.content; }).join('\n\r'); write(TITLE,result); var end = (new Date() - start ) / 1000; console.log("共耗时"+end+"秒"); }) }); var getData = function(item,callback){ var start = new Date(); Options.url = item.url; request(Options,function(err,res,body){ var end = (new Date() - start) / 1000; var str; if(err){ var str = `获取${item.url}失败,共耗时${end}秒\n\r`; callback(null,{ 'index':-1, 'title':'异常', 'content':'异常' }); message(11,str); }else{ body = iconv.decode(body,'gbk'); var $ = cheerio.load(body); var content = $('#content').text(); var str = `获取${item.url}成功,共耗时${end}秒\n\r`; var data = { "index":item.index, "title":item.title, "content":content }; callback(null,data); message(10,str); NUMBER++; console.log(`成功获取${NUMBER}个`); } }) }; var write = function(bookname,data){ var start = new Date(); console.log("开始写入文件"); fs.writeFileSync(bookname,data,'utf-8'); var end = ( new Date() - start ) / 1000; console.log(`写入文件成功,耗时${end}秒`); } // 每个请求的信息,success or false var message = function(type,data){ var name a8a7 = 'success.txt'; var options = { 'flag':'a+', 'encoding':'utf-8' } //success if(type == 11){ name = 'error.txt'; } fs.writeFile(name,data,options,function(err){ if(err){ console.log(err); } }) }
总结
其实也没什么好说的,就是各种npm的综合使用,值得注意的就是程序里的一下细节处理,爬取到的内容是先保存的内存中好,还是储存在外部文件中?爬取到内容的应该如何排序?等问题.相关文章推荐
- nodejs实现的爬虫,从百度贴吧爬取小说
- nodejs爬虫-妹子图,微信公众号文章,小说
- nodejs之异步流程控制ASYNC
- nodejs链接mysql数据库,执行简单的增删改查操作
- nodejs 安装配置和调试
- NodeJs 实现IOS APNS 消息推送服务
- nodejs安装express
- windows系统下nodejs、npm、express的下载和安装教程——2016.11.09
- nodejs模块调用
- nodejs服务启动程序
- windows 下安装nodejs
- nodeJS学习(4)--- webstorm/...开发 NodeJS 项目-节1
- Nodejs根据字符串调用对象方法
- NodeJS Buffer(缓冲区)
- nodejs全局安装和本地安装的区别
- forever让nodejs应用后台执行
- 尝尝nodeJs 的味道
- Nodejs项目部署阿里云完整流程
- NodeJS优缺点及适用场景讨论 .
- nodejs-创建Express实例