视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
使用Node.js爬虫如何实现网页请求
2020-11-27 19:37:44 责编:小采
文档


本篇文章主要介绍了浅谈Node.js爬虫之网页请求模块,现在分享给大家,也给大家做个参考。

本文介绍了Node.js爬虫之网页请求模块,分享给大家,具体如下:

注:如您下载最新的nodegrass版本,由于部分方法已经更新,本文的例子已经不再适应,详细请查看开源地址中的例子。

一、为什么我要写这样一个模块?

源于笔者想使用Node.js写一个爬虫,虽然Node.js官方API提供的请求远程资源的方法已经非常简便,具体参考

http://nodejs.org/api/http.html 其中对于Http的请求提供了,http.get(options, callback)和http.request(options, callback)两个方法,

看方法便知,get方法用于get方式的请求,而request方法提供更多的参数,例如其它请求方式,请求主机的端口等等。对于Https的请求于Http类似。一个最简单的例子:

var https = require('https');
https.get('https://encrypted.google.com/', function(res) {
 console.log("statusCode: ", res.statusCode);
 console.log("headers: ", res.headers);

 res.on('data', function(d) {
 process.stdout.write(d);
 });

}).on('error', function(e) {
 console.error(e);
});

对于以上代码,我们无非就是想请求远程主机,得到响应信息,例如响应状态,响应头,响应主体内容。其中get方法的第二个参数是一个回调函数,我们异步的获取响应信息,然后,在该回调函数中,res对象又监听data,on方法中第二个参数又是一个回调,而你得到d(你请求到的响应信息)后,很可能在对它进行操作的时候再次引入回调,一层层下去,最后就晕了。。对于异步方式的编程,对于一些习惯同步方式写代码的同学是非常纠结的,当然国内外已经对此提供了一些非常优秀的同步类库,例如老赵的Wind.js......好像有点扯远了。其实,我们调用get最终要得到的无非就是响应信息,而不关心res.on这样的监听过程,因为太懒惰。不想每次都res.on('data',func),于是诞生了今天我要介绍的nodegrass。

二、nodegrass请求资源,像Jquery的$.get(url,func)

一个最简单的例子:

var nodegrass = require('nodegrass');
nodegrass.get("http://www.baidu.com",function(data,status,headers){
 console.log(status);
 console.log(headers);
 console.log(data);
},'gbk').on('error', function(e) {
 console.log("Got error: " + e.message);
});

咋一看,和官方原来的get没啥区别,确实差不多=。=!只不过少了一层res.on('data',func)的事件监听回调而已。不管你信不信,反正我看上去感觉舒服多了,第二个参数同样是一个回调函数,其中的参数data是响应主体内容,status是响应状态,headers是响应头。得到响应内容,我们就可以对得到的资源提取任何我们感兴趣的信息啦。当然这个例子中,只是简单的打印的控制台而已。第三个参数是字符编码,目前Node.js不支持gbk,这里nodegrass内部引用了iconv-lite进行了处理,所以,如果你请求的网页编码是gbk的,例如百度。只需加上这个参数就行了。

那么对于https的请求呢?如果是官方api,你得引入https模块,但是请求的get方法等和http类似,于是nodegrass顺便把他们整合在一块了。看例子:

var nodegrass = require('nodegrass');
nodegrass.get("https://github.com",function(data,status,headers){
 console.log(status);
 console.log(headers);
 console.log(data);
},'utf8').on('error', function(e) {
 console.log("Got error: " + e.message);
});

nodegrass会根据url自动识别是http还是https,当然你的url必须得有,不能只写www.baidu.com/而需要http://www.baidu.com/。

对于post的请求,nodegrass提供了post方法,看例子:

var ng=require('nodegrass');
ng.post("https://api.weibo.com/oauth2/access_token",function(data,status,headers){
 var accessToken = JSON.parse(data);
 var err = null;
 if(accessToken.error){
 err = accessToken;
 }
 callback(err,accessToken);
 },headers,options,'utf8');

以上是新浪微博Auth2.0请求accessToken的一部分,其中使用nodegrass的post请求access_token的api。

post方法相比get方法多提供了headers请求头参数,options--post的数据,它们都是对象字面量的类型:

var headers = {
 'Content-Type': 'application/x-www-form-urlencoded',
 'Content-Length':data.length
 };

var options = {
 client_id : 'id',
 client_secret : 'cs',
 grant_type : 'authorization_code',
 redirect_uri : 'your callback url',
 code: acode
 };

三、利用nodegrass做代理服务器?……**

看例子:

var ng = require('nodegrass'),
 http=require('http'),
 url=require('url');

 http.createServer(function(req,res){
 var pathname = url.parse(req.url).pathname;
 
 if(pathname === '/'){
 ng.get('http://www.cnblogs.com/',function(data){
 res.writeHeader(200,{'Content-Type':'text/html;charset=utf-8'});
 res.write(data+"\n");
 res.end();
 },'utf8');
 }
 }).listen(8088);
 console.log('server listening 8088...');

就这么简单,当然代理服务器还有复杂的多,这个不算是,但至少你访问本地8088端口,看到的是不是博客园的页面呢?

nodegrass的开源地址:https://github.com/scottkiss/nodegrass

上面是我整理给大家的,希望今后会对大家有帮助。

相关文章:

JavaScript递归遍历和非递归遍历

vue中如何使用element-ui的Upload上传组件

vue中如何实现methods方法之间调用

下载本文
显示全文
专题