nodejs抓取动态网页(之前做爬虫的优劣)
优采云 发布时间: 2022-01-02 07:15nodejs抓取动态网页(之前做爬虫的优劣)
欢迎访问我的博客杨辰的博客
简介
说到爬虫,最容易想到的就是python了,因为python感觉它什么都能做,但是之前用python做爬虫的过程还是很不爽。主要问题来自几个方面:第一个是对的,对于被爬取的网页的dom操作,第二个是编码处理,第三个是多线程,所以用python做爬虫其实不是很爽。有没有更好的办法?当然还有node.js!
Nodejs作为爬虫的优缺点 首先说一下node作为爬虫的优点
第一个是他的驱动语言是 JavaScript。在 nodejs 诞生之前,JavaScript 是一种运行在浏览器上的脚本语言。它的优点是对网页上的dom元素进行操作,在网页操作方面是其他语言无法比拟的。
二是nodejs是单线程异步的。听起来很奇怪,单线程怎么可能是异步的?想一想为什么在学习操作系统时单核cpu可以进行多任务处理?原因是类似的。在操作系统中,进程占用CPU时间片。每个进程占用的时间很短,但是所有进程都循环了很多次,所以看起来像是同时处理多个任务。对于 js 也是如此。 js中有一个事件池。 CPU会在事件池循环中处理响应的事件,未处理的事件不会放入事件池中,因此不会阻塞后续操作。这样做在爬虫上的好处是,在并发爬取的页面上,一个页面返回失败不会阻塞后续页面继续加载。要做到这一点,你不需要像 python 那样多线程。
接下来是node的缺点
首先,它是异步和并发的。处理好很方便,但是处理不好就麻烦了。比如要爬10个页面,使用node不做异步处理,返回的结果不一定在1、2、3、4...... 这个顺序很可能是随机的。解决办法是添加一个页面序列戳,让爬取的数据生成一个csv文件,然后重新排序。
第二个是数据处理的劣势。这不如python。如果只是单纯的爬取数据,用node当然好,但是如果用爬取的数据继续做统计分析,那就做回归分析。什么东西,那你就不能用node了。
如何使用nodejs作为爬虫
接下来说一下如何使用nodejs作为爬虫
1、初始项目文件
在对应的项目文件夹下执行npm init初始化一个package.json文件
2、安装请求和cheerio依赖包
request 听起来很熟悉,就像 Python 中的 request 函数一样。它的作用是建立目标网页的链接并返回相应的数据,不难理解。
Cheerio 的函数用于操作 dom 元素。它可以将请求返回的数据转换成dom可以操作的数据。更重要的是,cheerio的api和jquery是一样的。用$选择对应的dom节点,是不是很方便?对于前端程序员来说,这比python的xpath和beautisoup方便多了。不知道多少钱啊哈哈
安装命令也很简单,就是npm install request --save和npm installcheerio
3、引入依赖包并使用
接下来用request和cherrio写一个爬虫!
先引入依赖
var request = require("request");
var cheerio = require("cheerio");
接下来我们以爬取我们学校的新闻页面为例。我们学校新闻页面的链接是
然后调用请求接口
request('http://news.shu.edu.cn/Default.aspx?tabid=446',function(err,result){
if(err){
console.log(err);
}
console.log(result.body);
})
运行一下,结果是这样的
你很兴奋吗?哈哈,html又回来了。这还不够。下一步就是对返回的数据进行处理,提取我们想要获取的信息。轮到啦啦队了。
将请求返回的结果传入cheerio,得到想要获取的信息。代码有没有想写脚本的感觉?
request('http://news.shu.edu.cn/Default.aspx?tabid=446',function(err,result){
if(err){
console.log(err);
}
var $ = cheerio.load(result.body);
$('a[id^="dnn"]').each(function(index,element){
console.log($(element).text());
})
})
运行结果如下:
这样一个简单的爬虫就完成了。是不是很简单?当然,这还远远不够。
4、设置请求头
众所周知,在http协议中,发送请求头是为了建立连接。对于一些动态网页的抓取,有时需要设置用户代理、cookies等,那么如何使用这些设置?
具体案例代码如下:
var options = {
url: startUrl+'?page=1',
method: 'GET',
charset: "utf-8",
headers: {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.93 Safari/537.36",
"cookie": cookies
}
};
request(options,function(err,response,body){
//...
})
5 并发控制
可以抓取页面。如果页面多,就会有无限的并发,那么肯定会被阻塞,所以一定要有并发控制。这里是异步的。和上面一样,需要通过npm install async --save安装,通过var async = require("async")引入。
举一个具体的例子来限制并发。
async.mapLimit(5,function(url,callback)){
//...
fetch(url,callback)
})
这里的5是并发数的限制,可以自由使用。最后,不要忘记执行后的回调,因为如果没有,它会被阻塞。 Async 不知道被限制的函数是否已经执行,所以不会被释放。
总结
至此,Nodejs爬虫的核心已经介绍完毕,剩下的就完全可以自由发挥了。最后附上我自己做的一个简单的新浪微博爬虫