一个简单的小说爬虫
平时,我有看小说的习惯。
前段时间,在学 node 的过程中突然想到,我可以用 node 去爬小说。
说来就来。
1、首先,要有一个能够免费看小说的网站,找到小说的列表页,分析其中每个章节的标签,找到其中的规则,这样可以在代码中把重复的去掉。
2、通过 node 中的 http 模块加载这个列表页面,采用 cheerio 模块解析加载回来的 html,取到一个没有重复章节的列表。(列表中有章节名,章节的地址)。
3、分析章节页面的标签,掌握章节页面的标签规则。
4、加载章节页面,解析 html ,取到章节的内容。
5、利用 node 的 file 模块将取到的内容写到电脑的硬盘上。
4,5 是根据 2 取回来的章节列表重复执行的。
好了,不说,上代码
util.js
const path = require(\'path\'); const utils = { resolve: function(dir) { return path.join(__dirname, \'../\', dir) }, } module.exports = utils;
index.js
const getHttp = require(\'./request.js\');
getHttp();
request.js
const http = require(\'http\'); const cheerio = require(\'cheerio\'); const config = require(\'./config.js\'); const file = require(\'./file.js\'); function getHttp(filePath, callback) { http.get(config.href + filePath, function(res) { var html = \'\'; res.setEncoding(\'utf-8\'); res.on(\'data\', function(data) { html += data; }); res.on(\'end\', function() { var $ = cheerio.load(html); //采用cheerio模块解析html var font = $(\'#htmlContent\').find(\'p\'); var j = -1; function fonts() { j++; if (j >= font.length) { callback(); return; } file.writeFile($(font[j]).text(), fonts); } fonts(); }); res.on(\'error\', function(err) { console.log(err); }); }) } function getUrl() { http.get(config.href + \'index.html\', function(res) { var html = \'\'; res.setEncoding(\'utf-8\'); res.on(\'data\', function(data) { html += data; }); res.on(\'end\', function() { var $ = cheerio.load(html); //采用cheerio模块解析html var ul = $(\'.wrapper_list .booklist\').find(\'ul\'); var a = $(ul).find(\'li>a\'); var i = 8; function wriert() { i++; console.log(i - 8); if (i >= a.length) { return; } file.writeFile($(a[i]).text().replace(\'正文\', \'\')); getHttp($(a[i]).attr(\'href\'), wriert); } wriert(); }); res.on(\'error\', function(err) { console.log(err); }); }) } module.exports = getUrl;
file.js
const utils = require(\'./utils.js\'); const config = require(\'./config.js\'); const cheerio = require(\'cheerio\'); const fs = require(\'fs\'); var file = {} file.writeFile = function(p, callback) { var folder = utils.resolve(config.folder); fs.access(folder, fs.constants.R_OK | fs.constants.W_OK, function(e) { if (e) { fs.mkdir(folder, function() { file.write(p, callback); }) } else { file.write(p, callback); } }); } file.write = function(p, callback) { var url = utils.resolve(config.folder + \'/\' + config.name + \'.txt\'); if (fs.existsSync(url)) { fs.appendFileSync(url, \'\r\n\' + p + \'\r\n\'); callback && callback(); } else { fs.writeFileSync(url, \'\r\n\' + p + \'\r\n\'); callback && callback(); } } module.exports = file;
config.js
const config = { href: \'http://www.qtshu.com/xinghedadi/\', name: \'星河大帝\', folder: \'novel\', }; module.exports = config;