http模块内部封装了http服务器和客户端,因此Node.js不需要借助Apache、IIS、Nginx、Tomcat等传统HTTP服务器,就可以构建http服务器,亦可以用来做一些爬虫。下面简单介绍该模块的使用,其具体API,大家可以自行去nodejs官方文档查看。
1、http.Server服务器
使用http.createServer([requestListener])方法创建一个http服务器,该方法返回一个新的http.Server实例,如果指定了requestListener,则会自动添加request事件。http.Server继承于net.Server,故默认拥有很多的属性、方法和事件,如下图所示(只给出部分):
使用如下所示:
代码中的request事件监听的参数req,res分别是http.IncomingMessage,http.ServerResponse的实例,IncomingMessage对象是由 http.Server 或 http.ClientRequest 创建,并且被自动添加到'request' and 'response' 事件监听函数的第一个参数,是一个可读流,主要包括一些状态信息,请求信息,属性如下所示:
ServerResponse对象是HTTP server内部创建,并作为request事件监听函数的第二个参数,实现了可写流,决定返回给客户端的内容,属性如下所示:
创建一个http服务器,并监听3000端口,用浏览器打开http://127.0.0.1:3000浏览,即可看到hello world。 我们还可以创建一个简易的路由,对用户的请求进行处理,如下所示:
2、http.ClientRequest客户端
该对象通过http.request()或http.get()方法创建,可以作为一个向服务器发起请求的客户端,该对象的属性(只列出部分)如下:
http.request(options[,callback])方法使用
参数options可以是一个对象或字符串,如果是字符串则会自动调用url.parse()进行解析,包涵以下属性(部分):
- protocol,协议,默认为http:
- host,主机地址
- hostname,主机名
- family,IP版本
- port,端口
- method,请求方法
- path ,路径
- headers ,请求头
- timeout ,超时时间
callback会自动添加给reponse事件监听,返回值为http.ClientRequest,下面利用该知识写一个利用支付宝接口查询银行卡号所属银行,不过http换成了https,接口一致,代码如下:
console.log(
参数错误,请输入16位以上银行卡号。例如:node http-get.js 6228430120000000000
);process.exit(0);
}
baseUrl = baseUrl + cardNo;
const client = https.get(baseUrl,(res) => {
const status = res.statusCode;
const type = res.headers['content-type'];
let msg = '';
let data = '';
if (status !== 200) {
msg = '发送请求失败 code:' + statusCode;
} else if (!/^application\/json/.test(type)) {
msg = '返回的数据格式不正确,应返回JSON';
}
if (msg != '') {
console.log(msg);
process.exit(0);
}
res.setEncoding('utf8');
res.on('data',(chunk) => {
data += chunk;
});
res.on('end',() => {
try {
let bankObj = JSON.parse(data);
dealBankObj(bankObj);
} catch (e) {
console.log(e.message);
}
});
});
client.on('error',(err) => {
console.log(err.message);
});
function dealBankObj(obj) {
const bname = banknames[obj['bank']];
const btype = obj['cardType'];
const cardId = obj['key'];
console.log(卡号:${cardNo}\r\n银行:${bname}\r\n类型:${btypes[btype]}
);
}
bankname.js
执行结果如下所示:
E:\developmentdocument\nodejsdemo>node http-get.js 6228430120000000000
卡号:6228430120000000000
银行:中国农业银行
类型:借记卡
下面再举一个爬虫例子,利用百度和360搜索的数据,验证电话号码是否骚扰电话,需要cheerio库,该库类似jquery,语法大部分一致,使用npm安装:
npm install cheerio
我们对两个搜索引擎搜索指定电话号码的结果进行分析,如果是骚扰号码则打印出被标记多少次,否则打印其归属地,实现如下所示:
host: 'www.baidu.com',port: 80,path: '/s?wd=' + num,method: 'GET'
};
var options360 = {
host: 'www.so.com',port: 443,path: '/s?q=' + num,method: 'GET'
};
if (!/^\d+$/.test(num)) {
console.log(参数错误,请输入正确电话号码或查询平台。\r\n例如:node phoneMark.js 15949566632
);
process.exit(0);
}
function request(protocol,options,cb) {
return new Promise((resolve,reject) => {
var req = protocol.request(options,(res) => {
var html = '';
res.setEncoding('utf8');
res.on('data',(chunk) => {
html += chunk;
});
res.on('end',() => {
resolve(cb(html));
});
});
req.on('error',(err) => {
reject(err);
});
req.end();
});
}
Promise
.all([request(http,optionsBD,AnalysizeByBD),request(https,options360,AnalysizeBy360)])
.then((vals) => {
summary(vals);
},(err) => {
console.log(err);
});
function summary(vals) {
if ((/\d+/g).test(vals[0])) {
console.log(号码${num}:为骚扰号码,分别被<a href="/tag/baidu/" target="_blank" class="keywords">百度</a>、360<a href="/tag/biaoji/" target="_blank" class="keywords">标记</a>${vals[0]}、${vals[1]}次
);
} else {
console.log(号码${num}:${vals[0]}
);
}
}
function AnalysizeByBD(html) {
var $ = cheerio.load(html);
var arr = $('.op_fraudphone_word').text().trim().replace(/\s+/g,"").match(/(\d+)/g)
return arr ? arr[0] : $('.op_mobilephone_r').find('span').eq(1).text().replace(/\s*/g,"");
}
function AnalysizeBy360(html) {
var $ = cheerio.load(html);
return $('.mohe-tips').find('b').text();
}
执行结果如下:
E:\developmentdocument\nodejsdemo>node number.js 15656069453
号码15656069453:为骚扰号码,分别被百度、360标记12、8502次
http模块便介绍到这。