目标:爬取免费小说网站 和 免费视频网站
为什么爬取免费网站呢?
主要是我认为所有像优酷、腾讯或者起点这类会员制网站,资源是一定会有用户信息认证的。
常规手段基本不可能伪造出有效的认证信息,单纯靠爬虫是无法获得最终结果的。
当然这只是一个小小小前端当下的无知之言。以后发现错了以后改。
言归正传,现在开始讲一下爬虫的过程。
工欲善其事,必先利其器。
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');
把整个过程分为两个部分吧,至于为什么要分成这两部分,文中会讲。
- 小说:
这部分属于爬虫的基础部分,我们只需要爬取目标网站的内容就行。
首先准备两个工具函数:
- 获取页面信息
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
可以获取到页面的数据了。
- 解析页面信息
// 解析页面
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解析文档数据并提供遍历或操作这些文档的api(所以才说它像jquery嘛)。但不会去渲染结果,不会加载css或其他外部资源,更不会执行脚本。如果我们要用到上述功能,cheerio建议我们考虑使用PhantomJS或者JSDom。
我这里选择了jsdom。
先写到这里,后续更新。
网友评论