简单用 node 整个 JS 爬虫
我这里其实不是单纯的爬 html 我是把他们 api 给抓出来了,然后直接 POST api 获取的数据,其实最主要是 node post 这一块卡了我比较久,我刚开始一直用官方的 https 模块,然后官方文档还写的简洁得一批,我基础又不是很好十分难受
然后我就在全网找相应的博客,直到我看到有一篇博客说 request 这个东西,我才恍然大悟我TD开头就是错的,为啥一直纠着 https 不放呢…
好了,进入正题
首先我这里用到两个模块 require("fs") 文件操作,require("request") 网络操作
然后就是三个辅助方法,xrFile 写入文件,downloadFile 下载文件,fsExistsSync 判断文件夹是否存在
/*
* file 文件路径
* body 内容
* fun 回调方法
*/
function xrFile(file, body, fun) {
fs.writeFile(file, body, function(err) {
if (err) {
return console.error(err);
}
// console.log("数据写入成功!");
fun();
});
}
/*
* url 网络文件地址
* filename 文件名
* callback 回调函数
*/
function downloadFile(uri, filename, callback) {
var stream = fs.createWriteStream(filename);
request(uri)
.pipe(stream)
.on("close", callback);
}
// 判断文件夹是否存在
function fsExistsSync(path) {
try {
fs.accessSync(path, fs.F_OK);
} catch (e) {
return false;
}
return true;
}
先看看我整个代码:
const fs = require("fs");
var request = require("request");
/*
* file 文件路径
* body 内容
* fun 回调方法
*/
function xrFile(file, body, fun) {
fs.writeFile(file, body, function(err) {
if (err) {
return console.error(err);
}
// console.log("数据写入成功!");
fun();
});
}
/*
* url 网络文件地址
* filename 文件名
* callback 回调函数
*/
function downloadFile(uri, filename, callback) {
var stream = fs.createWriteStream(filename);
request(uri)
.pipe(stream)
.on("close", callback);
}
// 判断文件夹是否存在
function fsExistsSync(path) {
try {
fs.accessSync(path, fs.F_OK);
} catch (e) {
return false;
}
return true;
}
function main() {
// 获取数据
request.post(
{
url: "https://share.xxxxxxx.com/api/share/rec_video",
json: true
},
function(err, httpResponse, body) {
if (httpResponse.statusCode === 200) {
// process.stdout.write(d);
fs.writeFile("./data/video_list.json", JSON.stringify(body), function(
err
) {
if (err) {
return console.error(err);
}
// console.log("数据写入成功!");
// let obj = JSON.parse(body);
let list = body.data.list;
for (let i in list) {
const data = list[i];
if (data.content !== "") {
// console.log(data.content);
const filePath = "./data/video/" + data.id;
// 发送 Post 函数获取视频数据
request.post(
{
url: "https://share.xxxxxx.com/api/post/detail",
json: true,
body: {
h_av: "3.0",
h_dt: 9,
h_nt: 9,
h_ch: "web_app",
ua:
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.120 Safari/537.36",
pid: data.id
}
},
function(err, httpResponse, body) {
// 请求完成之后的回调函数
// console.log(body);
const v_data = body.data.post;
for (const v_s in v_data.videos) {
let v_json = v_data.videos[v_s];
// console.log(v_json.dur);
// 排除视频时长大于60秒的
if (v_json.dur <= 60 && !fsExistsSync(filePath)) {
fs.mkdir(filePath, function() {
downloadFile(
v_json.url,
filePath + "/v_" + v_s + ".mp4",
function() {
// console.log("下载成功");
const video_data = {
zy_id: data.id,
content: v_data.content,
date: v_json.dur,
user: {
name: v_data.member
}
};
xrFile(
filePath + "/data.json",
JSON.stringify(video_data),
function() {
console.log(
"视频:" + data.id,
" 时长:" + v_json.dur,
" 介绍:" + v_data.content
);
}
);
}
);
});
} else {
console.log("视频过长!或视频已经存在!");
}
}
}
);
}
}
});
} else {
console.log("请求错误,code:", httpResponse.statusCode);
}
}
);
}
main();
api 我还是给整掉吧,以免…
这里主要还是 request 的使用,Github地址:https://github.com/request/request
先导入这个模块
npm install request --save
GET 请求
var url = 'http://192.168.0.102:3000/home?name=xmg'
// 发送Get请求
// 第一个参数:请求的完整URL,包括参数
// 第二个参数:请求结果回调函数,会传入3个参数,第一个错误,第二个响应对象,第三个请求数据
request(url,function (error, response, data) {
console.log(data)
});
Post 请求
post请求有3种方式,由请求头中的content-type决定,属于哪一种post请求
application/x-www-form-urlencoded: 普通http请求方式,参数是普通的url参数拼接
application/json: JSON请求方式,参数是json格式
multipart/form-data: 文件上传
application/x-www-form-urlencoded
var url = 'http://192.168.0.102:3000/home?name=xmg'
request.post({url:url, form:{key:'value'}}, function(error, response, body) {
if (!error && response.statusCode == 200) {
}
})
application/json
var url = 'http://192.168.0.102:3000/home'
request({
url: url,
method: "POST",
json: true,
headers: {
"content-type": "application/json",
},
body: JSON.stringify(requestData)
}, function(error, response, body) {
if (!error && response.statusCode == 200) {
}
});
multipart/form-data
var url = 'http://192.168.0.102:3000/home'
var formData = {
// Pass a simple key-value pair
my_field: 'my_value',
// Pass data via Buffers
my_buffer: new Buffer([1, 2, 3]),
// Pass data via Streams
my_file: fs.createReadStream(__dirname + '/unicycle.jpg'),
};
request.post({url:url, formData: formData}, function (error, response, body) {
if (!error && response.statusCode == 200) {
}
})