一个简单的小说爬虫

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

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

 

posted @ 2018-01-19 18:49  青风无痕  阅读(465)  评论(0编辑  收藏  举报