背景与需求分析
最近迷恋于王者荣耀、斗鱼直播与B站吃播视频,中毒太深,下班之后无心看书。
为了摆脱现状,能习惯看书,我开始看小说了,然而小说网站广告多而烦,屌丝心态不愿充钱,于是想到了爬虫。
功能分析
为了将网上小说内容获取到本地,进行了功能分析:
1、获取每个章节列表地址
2、更加每个章节地址,获取每个章节的内容
3、将获取的各个章节内容有序的写入文件
技术调研
作为一个前端er,实现爬虫nodeJS必须是首选,虽然数据挖掘Python才是真理
npm依赖如下
1、爬取内容 superagent
2、分析爬取的内容 cheerio
3、并发 async
4、文件写入 fs
编码实现
xiaoshuo.js代码如下
const cheerio = require('cheerio') const superagent = require('superagent') require('superagent-charset')(superagent) const async = require('async'); const fs = require('fs'); let baseUrl = 'http://www.xxx.com/book/14435/'; let infos = []; let urls = []; let titles = []; let fileName = ''; superagent.get(baseUrl).charset('UTF-8').end((err,res)=>{ var $ = cheerio.load(res.text); // 读取章节列表页面 $('.am-book-list').eq(1).find('.am-u-lg-4 a').each((i, v) => { let link = 'http://www.xxx.com' + $(v).attr('href') urls.push(link); fileName = $('.am-book-info h2').text()+'.txt'; }) let id = 0; //获取每个章节列表 async.mapLimit(urls,urls.length,(url,callback)=>{ id++ fetchUrl(url,callback,id); },(err,results)=>{ //将文件写入本地 fs.existsSync(fileName); for(var i = 0;i<results.length-1;i++){ fs.appendFileSync(fileName, results[i].title) // fs.appendFileSync(fileName, results[i].content) } }) }) function fetchUrl(url,callback,id){ superagent.get(url) .charset('UTF-8') .end(function(err,res){ let $ = cheerio.load(res.text); let arr = [] let content = reconvert($("#am-read-centent").text()) const obj = { id: id, err: 0, title: ' '+$('#am-book-h3').text(), //标题 content: ' '+trim(content.toString()) //内容 } callback(null,obj) }) } function reconvert(str) { str = str.replace(/(&#x)(w{1,4});/gi, function ($0) { return String.fromCharCode(parseInt(escape($0).replace(/(%26%23x)(w{1,4})(%3B)/g, "$2"), 16)); }); return str } function trim(str){ return str.replace(/(^s*)|(s*$)/g, '').replace(/ /g, '') }
为了避免坐牢,站点使用xxx代替,
运行效果
在命令行运行 node xiaoshuo,试验了本小说,好像还是ok的,哈哈哈