美文网首页
nodejs使用axios+cheerio完成网站静态爬取操作

nodejs使用axios+cheerio完成网站静态爬取操作

作者: 某时橙 | 来源:发表于2020-07-25 15:04 被阅读0次

part1:写在前面

如果仅仅只是使用axios+cheerio,那么只能完成对网页的静态爬取,要模拟一些dom操作获取动态资源,就必须使用一些特殊的技巧。比如Headless Chromium。

part2:库介绍

axios

什么是 axios?
Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中。
浏览器:中我们用axios完成对后台接口的调用,因为它封装了许多方法比如get和post,比起我们自己手写ajax轮子来说,这方便了许多,但在本文中,由于使用的是nodejs,这里就不多展开。
node:使用axios.get可以实现对网站的get请求,请求回来的响应信息中有我们需求的html资源,下面的文章会对node中的axios详细展开描述。

cheerio:

node版jquery,但是无法触发元素上的事件(因为响应信息实际上只是字符串版的html信息)

part3:实例操作

在码代码前需要下载axios,cheerio库,具体方法详见官方文档。

var cheerio = require('cheerio')  //只能用于jq式的解析html,但注意是解析,所以不能进行事件操作
axios.get('https://www.bilibili.com/')
    .then(function (res) {
        // 获取网页数据
       console.log(res);

    })
    .catch(function (err) {
        console.log('failed', err);
    });

使用node 文件名.js启动脚本,
但很可惜,第一次尝试,失败。

结果:失败.png
注意错误原因Error: Request failed with status code 403
403很明显是http错误码,

403错误是一种在网站访问过程中,常见的错误提示,表示资源不可用。服务器理解客户的请求,但拒绝处理它,通常由于服务器上文件或目录的权限设置导致的WEB访问错误。
如果你了解http请求,那么你一定知道,请求报文中是包含请求头的,但我们的代码中,很明显没有对请求头进行配置,

那么,如何获取请求头的详细信息?
使用浏览器审查元素即可。


往下翻,我们可以找到request header,这就是我们需要的请求头信息。

get的第二个参数可以写入相关配置,这里我们用es6语法直接引入header

var axios = require('axios');
var cheerio = require('cheerio')  //只能用于jq式的解析html,但注意是解析,所以不能进行事件操作
let headers={
    authority:"x",
    method: "x",
    path: "x",
    scheme: "x",
    accept: "x",
    acceptEncoding: "x",
    acceptLanguage: "x",
    cacheControl:"x",
    cookie:"x",
    secFetchDest:"x",
    secFetchMode:"x",
    secFetchSite:"x",
    secFetchUser:"x",
    upgradeInsecureRequests:"x",
    userAgent:"x",
}
axios.get('https://www.bilibili.com/', {headers})
    .then(function (res) {
        // 获取网页数据
      console.log(res);

    })
    .catch(function (err) {
        console.log('failed', err);
    });
这下我们就爬取成功了! image.png

但是怎么总感觉怪怪的?
类似于\uxxxx的字符串格式非常的多,
实际上这是unicode编码,我们只需要进一步转换即可
将第一个then中的内容改为

let text=unescape((res.data).replace(/\\u/g, '%u')) //将unicode码转换成中文

你就可以看到正确的内容了。


image.png

接下来,让我们使用cheerio抓取我们想要的信息。
第一步:
为$赋予意义,使用cheerio.load即可
代码如下:

let $ = cheerio.load(text, {
      decodeEntities: false,
    });

decodeEntities是一个配置选项,也是为了解决中文乱码问题所设置,如果不设置爬下来的数据也依然会乱码。

这里,我们想爬取首页视频信息,那么我们继续审查元素


image.png

那么基本可以锁定是.info-box下的.title元素,包含了我们要的信息。
利用jq语法,我们可以得到我们要的数据:
最终代码如下:

var axios = require("axios");
var cheerio = require("cheerio"); //只能用于jq式的解析html,但注意是解析,所以不能进行事件操作
let headers={
    authority:"x",
    method: "x",
    path: "x",
    scheme: "x",
    accept: "x",
    acceptEncoding: "x",
    acceptLanguage: "x",
    cacheControl:"x",
    cookie:"x",
    secFetchDest:"x",
    secFetchMode:"x",
    secFetchSite:"x",
    secFetchUser:"x",
    upgradeInsecureRequests:"x",
    userAgent:"x",
}
axios
  .get("https://www.bilibili.com/", { headers })
  .then(function (res) {
    // 获取网页数据
    let text = unescape(res.data.replace(/\\u/g, "%u")); //将unicode码转换成中文
    let $ = cheerio.load(text, {
      decodeEntities: false,
    });
    console.log("首页推荐" + "in " + new Date().toString());
    $(".video-card-reco .info .title").each(function () {
      let text = $(this).html();
      console.log(text);
    });
  })
  .catch(function (err) {
    console.log("failed", err);
  });

数据:


image.png

相关文章

网友评论

      本文标题:nodejs使用axios+cheerio完成网站静态爬取操作

      本文链接:https://www.haomeiwen.com/subject/rfiplktx.html