前段时间,在学 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;