前言
本文给大家介绍的爬虫将从网站爬取排名前几的网站,具体前几名可以具体设置,并分别爬取他们的主页,检查是否引用特定库。下面话不多说了,来一起看看详细的介绍:
所用到的node主要模块
express 不用多说 request http模块 cheerio 运行在服务器端的jQuery node-inspector node调试模块 node-dev 修改文件后自动重启app关于调试Node
在任意一个文件夹,执行node-inspector,通过打开特定页面,在页面上进行调试,然后运行app,使用node-dev app.js来自动重启应用。
所碰到的问题
1. request请求多个页面
由于请求是异步执行的,和分别返回3个页面的数据,这里只爬取了50个网站,一个页面有20个,所以有3页,通过循环里套request请求,来实现。
通过添加请求头可以实现基本的反爬虫
处理数据的方法都写在analyData()
里面,造成后面的数据重复存储了,想了很久,才想到一个解决方法,后面会写到是怎么解决的。
for (var i = 1; i < len+1; i++) { (function(i){ var options = { url: 'http://www.alexa.cn/siterank/' + i, headers: { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36' } }; request(options, function (err, response, body) { analyData(body,rank); }) })(i) }
2. 多层回调
仔细观察代码,你会发现,处理数据的方法使用了如下的多层回调,也可以不使用回调,写在一个函数内部;因为,每层都要使用上一层的数据,造成了这样的写法。
function f1(data1){ f2(data1);}function f2(data2){ f3(data2);}function f3(data3){ f4(data4);}
3. 正则获取JS库
由于获取页面库,首先需要获取到script的src属性,然后通过正则来实现字符串匹配。
<script src="https://ss0.bdstatic.com/5aV1bjqh_Q23odCf/static/superman/js/lib/jquery-1.10.2_d88366fd.js"></script>
获取到的script可能是上面这样的,由于库名的命名真是各种各样,后来想了一下,因为文件名是用.js结尾的,所以就以点号为结尾,然后把点号之前的字符截取下来,这样获得了库名,代码如下。
var reg = /[^////]+$/g;var libName = jsLink.match(reg).join('');var libFilter = libName.slice(0,libName.indexOf('.'));
4.cheerio模块获取JS引用链接
这部分也花了一点时间,才搞定,cheerio获取DOM的方法和jQuery是一样的,需要对返回的DOM对象进行查看,就可以看到对象里隐藏好深的href属性,方法大同小异,你也可以使用其他选择器,选择到script标签
var $ = cheerio.load(body);var scriptFile = $('script').toArray();scriptFile.forEach(function(item,index){ if (item.attribs.src != null) { obtainLibName(item.attribs.src,index);}
新闻热点
疑难解答
图片精选