简单爬取静态网页
let fs = require("fs");
let url = require("url");
let JSDOM = require("jsdom").JSDOM;
let gbk = require("gbk");
// 通过url抓取数据
getUrl("https://www.zhihu.com/question/297320531",data=>{
// 转换data中的gbk编码为utf-8,某些网站可不做
let html = gbk.toString('utf-8',data);
// 1.写入 html 文件
fs.writeFile("a.html",html,()=>{
console.log('get success!');
});
// 2.获取文件中的某项数据
// 将字符数据转化为 html dom 对象
let DOM = new JSDOM(data);
let document = DOM.window.document;
// 通过querySelector找到具体数据所在的标签
let str = document.querySelector('.VoteButton--up').innerHTML;
// 打印获取数据
console.log(str);
});
// 封装的get函数
function getUrl(myUrl,success) {
let urlObj = url.parse(myUrl);
let http = {};
// 判断请求的类型是 http 或者是https
if (urlObj.protocol === 'http:'){
http = require('http');
}
else {
http = require('https');
}
//http发起request请求,去请求数据
let req = http.request({
//此处填写域名,不包含www,即:www.baidu.com,而不是 https://www.baidu.com
"hostname": urlObj.hostname,
//此处资源路径,即上面域名下的资源 /img/img1.jpg
"path": urlObj.path
},res=>{
//这里是为了防止地址重定向而设置,淘宝的商品页做了9次重定向,如果存在重定向,则else if
if(res.statusCode == 200){
//接收二进制流
let arr = [];
//接收字符流
let str = '';
//request发起的请求为POST请求,所以需要使用on绑定事件来接收数据
res.on('data',buffer=>{
arr.push(buffer);
str += buffer;
});
//接受数据完毕
res.on('end',()=>{
//进行二进制转码,此处可以根据不同网页的数据来确定使用二进制流或者是字符流
let b = Buffer.concat(arr);
//成功后把数据传入success回调
success && success(b);
})
// 如果存在重定向,则去请求的头部中拿到新的地址,继续getUrl,直到找到真正的地址
else if(res.statusCode == 302 || res.statusCode == 301){
//console.log(`我是第${index}次重定向`,res.headers.location);
// 继续拿到新的地址进行解析
GetUrl(res.headers.location,success)
}
});
req.end();
//如果资源没有找到,则返回 404
req.on('error',()=>{
console.log("404 NOT FOUND");
})
}