平时,我有看小说的习惯。

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

 

版权声明:本文为fenghen原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/fenghen/p/8318445.html