我这里其实不是单纯的爬 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) {
    }
})