使用node制作爬虫

目标:爬取免费小说网站 和 免费视频网站

为什么爬取免费网站呢?
主要是我认为所有像优酷、腾讯或者起点这类会员制网站,资源是一定会有用户信息认证的。
常规手段基本不可能伪造出有效的认证信息,单纯靠爬虫是无法获得最终结果的。
当然这只是一个小小小前端当下的无知之言。以后发现错了以后改。

言归正传,现在开始讲一下爬虫的过程。

工欲善其事,必先利其器。
request、cheerio、iconv-lite、gbk、jsdom。这些库是我们必须要用到的,先引用进来。

const request = require('request');
const cheerio = require('cheerio');
const jsdom = require("jsdom");
const { JSDOM } = jsdom;
const iconv = require('iconv-lite');
const gbk = require('gbk.js');

把整个过程分为两个部分吧,至于为什么要分成这两部分,文中会讲。

- 小说:

这部分属于爬虫的基础部分,我们只需要爬取目标网站的内容就行。
首先准备两个工具函数:

  1. 获取页面信息
function getDataByUrl(url) {
    return new Promise((resolve, reject) => {
        request({
            url,
            method: 'GET',
            encoding: null,
            headers: {
                'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36'
            }
        }, (err, res, body) => {
            if( err ) {
                reject(err);
            } else {
                resolve({res, body});
            }
        });
    });
}

这里使用到了request库,它是一个可以模拟客户端请求的框架,使用上也非常方便。
GitHub·request 这是项目地址,用法不赘述了,我这里也有代码。
需要注意的是:

  • encoding 必须是null,否则后面有些网站的编码会转换失败。
  • user-agent 是为了模仿浏览器访问,有些网站可能会把非浏览器访问的请求禁掉。(其实都是自欺欺人罢了,一般只要有反爬虫的系统,请求次数频繁都直接封ip的。如果要频繁爬取,一般会使用代理池的方法,当然涉及到突破反爬虫的内容就太多了,也不是重点。。。)
    现在通过 getDataByUrl 可以获取到页面的数据了。
  1. 解析页面信息
//  解析页面
function parseUrl(url, callback, isUtf8) {
    return getDataByUrl(url).then(urlData => {
        //  如果网站编码是GBK才转
        if( !isUtf8 ) {
            var parseData = iconv.decode(urlData.body, 'gbk').replace('charset=GBK', 'charset=UTF-8');
        } else {
            var parseData = urlData.body;
        }
        var querySelector = cheerio.load(parseData);
        return callback(querySelector, parseData, urlData);
    }).catch(err => {
        console.log(err);
    });
}

这里使用了cheerio、iconv-lite两个库。

cheerio:相当于node中的jquery。方便我们操作爬取的html内容。
项目地址:GitHub·cheerio
iconv-lite:处理中文转码的工具。由于小说网站多是gbk编码,我们拿到的返回数据中,中文都是乱码,所以我们会用到。
项目地址:GitHub·iconv-lite

这个函数返回的是最终通过iconv-lite转码,并通过cheerio解析后的数据了。
我这里通过回调传出了querySelector(相当于jquery对象),后面两个参数,解析后的数据和原始数据基本用不到。

ok,一切就绪,就这么简单,现在已经可以爬取页面数据了。
下面是目标网站的页面及源代码:


toplist.png
toplistcode.png

下面是我们的爬虫代码和爬取结果:

parseUrl('https://******.html', $ => {
    var topList = [];
    $('.mod').each(function () {
        var list = [];
        $(this).find('.phb_main ul').first().find('li.a3').each(function (index, li) {
            list.push($(li).find('a').text());
        });
        topList.push(list);
        console.log('《' + $(this).find('.mod_l').text() + ' 》');
        console.log(list);
        console.log('-------------------------------------------------------')
    });
});
consoletoplist.png

上面就是小说演示部分的全部全过程了,非常 hello world 吧。

- 视频

相对小说,视频就属于进阶了。(其实也没进阶到哪去。。。从 hello world 到 if else 吧。。。)
从这里开始,我们就不只是爬取页面数据,还要分析视频真实地址,获取到我们想要的内容。
通常情况下,一些免费视频站点的视频都是套在iframe中的。
不会直接给你video标签或者视频地址让你去爽。
而iframe中的内容又有可能是动态加载的。cheerio已经无法满足我们的需求了。
因为它根本获取不到iframe中动态加载的内容。这一点cheerio在项目中已经说明了:

cheerio.png

我英文很烂,这里说明一下仅仅是为了方便懒得仔细看文档的朋友。
大白话就是:cheerio解析文档数据并提供遍历或操作这些文档的api(所以才说它像jquery嘛)。但不会去渲染结果,不会加载css或其他外部资源,更不会执行脚本。如果我们要用到上述功能,cheerio建议我们考虑使用PhantomJS或者JSDom。

我这里选择了jsdom。


先写到这里,后续更新。

你可能感兴趣的:(使用node制作爬虫)