node爬............虫与sequelize使用(为什么一提爬虫就是豆瓣)

前言

爬虫大家应该都不陌生,通过一系列操作去爬取网页上的数据,最近也是在学习node数据库,下面就简单介绍一下,顺便爬取豆瓣读书的部分书籍名字图片作者等...(为什么提到爬虫就爬豆瓣呢),只作为练习,不做盈利等等,否则可能就有点"刑"了 下面就是我们要爬取的地址 book.douban.com/latest

准备工作

身为前端开发者,我们肯定对这个库很熟悉 axios,本次爬虫要用到了两大库 axios与cheerio。 下面是npm 地址,具体大家可以看对应的第三方库

axios:www.npmjs.com/package/axi...

cheerio:github.com/cheeriojs/c... sequelize:www.sequelize.cn/core-concep... cheeriojquery 核心功能的一个快速灵活而又简洁的实现,主要是为了用在服务器端需要对 DOM 进行操作的地方。大家可以简单的理解为用来解析 html 非常方便的工具。

第一步获取源代码

导入两个库,并获取源代码

js 复制代码
const axios = require("axios");
const cheerio = require("cheerio");
async function getBooks() {
  //获取豆瓣读书网页的源代码
  const resp = await axios.get("https://book.douban.com/latest");
  return resp.data;
}

根你在网站右键查看源代码是一样的

第二步从详情页拿数据

从这个页面上看,我们可以获取的信息很少,所以我们需要进入详情页才能获取更多的信息,所以我们打开控制台,查看可以发现,图片中有个a元素可以导航到详细页面,所以,我们第二步就是拿到每一个详情页的网址

js 复制代码
async function getBooksListUrl() {
  const html = await getBooks(); //拿到源代码
  const $ = cheerio.load(html); //使用load方法解析源代码
  const list = $(".chart-dashed-list .media .media__img a"); //找到指定的元素
  const links = list
    .map((i, ele) => {
      const herf = ele.attribs["href"]; //获取href地址
      return herf;
    })
    .get();
  return links;
}
}

第三步进入详情页获取信息

进入详情页后,我们发现如下所示,这里我们获取书名,作者,创作时间以及书籍图片(想获取更多大家可以自行按照这样的方式获取)

js 复制代码
async function getBookDetail(url) {
  const resp = await axios.get(url); //获取详情页的源代码
  const $ = cheerio.load(resp.data); //解析源代码
  const name = $("h1").text().trim(); //获取标题
  const imgurl = $("#mainpic img").attr("src"); //图片地址
  const author = $("#info span a").text(); //作者名字
  const date = $("#info span.pl");
  const result = date.filter((i, ele) => {
    return $(ele).text().includes("出版年");
  });
  const publishDate = result[0].nextSibling.nodeValue.trim(); //创作日期
  return {
    name,
    author,
    imgurl,
    publishDate,
  };
}

我们可以发现,标题是由一个h1元素包裹的,且没有第二个h1

图片地址我们可以发现实在id为mainpic的下面的img身上

作者名字,使用text()获取元素中的文字

日期稍微麻烦一点,可以看到,日期由.pl的兄弟元素,所以我们使用如下方式

js 复制代码
const date = $("#info span.pl");
  const result = date.filter((i, ele) => {
    return $(ele).text().includes("出版年"); //找到出版年元素
  });
  const publishDate = result[0].nextSibling.nodeValue.trim(); 
  //创作日期,使用nextSibling获取下一个元素,nodeValue拿到值,去空格

将数据存入数据库

首先我们使用sequelize创建数据库模型

建立连接

js 复制代码
const { Sequelize } = require("sequelize");
//数据库连接
const sequelize = new Sequelize("mySchoolDB", "root", "dizao06", {
  host: "localhost",
  // logging: null, //不记录日志

  timezone: "+08:00", //保证时间准确
  dialect:
    "mysql" /* one of 'mysql' | 'postgres' | 'sqlite' | 'mariadb' | 'mssql' | 'db2' | 'snowflake' | 'oracle' */,
});

module.exports = sequelize;

创建book模型

js 复制代码
const sequelize = require("./index");
const { DataTypes } = require("sequelize");
//创建模型对象,创建表
const Book = sequelize.define(
  "Book", //表名
  {
    //表列
    name: {
      type: DataTypes.STRING(50),
      allowNull: false,
    },
    imgurl: {
      type: DataTypes.STRING,
    },
    publishDate: {
      type: DataTypes.STRING,
      allowNull: false,
    },
    author: {
      type: DataTypes.STRING,
      allowNull: false,
    },
  },
  {
    //     freezeTableName: true, // false时  admin-->admins
    //   createdAt:false, // false 不生成这一列
    // updatedAt:false, // false 不生成
    paranoid: true, //设置后改表的数据不会真正的删除,而是增加一列deletedAt标识删除时间
  }
);
module.exports = Book;

初始化

js 复制代码
const sequelize = require("./index");
sequelize
  .sync({
    alter: true,
  })
  .then((e) => {
    console.log("同步完成");
  });

存入数据

js 复制代码
async function getBook() {
  const links = await getBooksListUrl(); //详情页地址
  const prom = links.map((e) => {
    return getBookDetail(e);
  });
  return Promise.all(prom); //使用promise.all方法等待异步完成
}

async function saveDB() {
  const book = await getBook();
  // console.log(book);
  await Book.bulkCreate(book);//使用bulkCreate存入多条数据
  console.log("书籍抓取成功");
}

saveDB();

全代码便于大家复制

js 复制代码
const axios = require("axios");
const cheerio = require("cheerio");
const Book = require("../models/Book");
// import
async function getBooks() {
  //获取豆瓣读书网页的源代码
  const resp = await axios.get("https://book.douban.com/latest");
  return resp.data;
}
async function getBooksListUrl() {
  const html = await getBooks(); //拿到源代码
  const $ = cheerio.load(html); //使用load方法解析源代码
  const list = $(".chart-dashed-list .media .media__img a"); //找到指定的元素
  const links = list
    .map((i, ele) => {
      const herf = ele.attribs["href"]; //获取href地址
      return herf;
    })
    .get();
  return links;
}

async function getBookDetail(url) {
  const resp = await axios.get(url); //获取详情页的源代码
  const $ = cheerio.load(resp.data); //解析源代码
  const name = $("h1").text().trim(); //获取标题
  const imgurl = $("#mainpic img").attr("src"); //图片地址
  const author = $("#info span a").text(); //作者名字
  const date = $("#info span.pl");
  const result = date.filter((i, ele) => {
    return $(ele).text().includes("出版年");
  });
  const publishDate = result[0].nextSibling.nodeValue.trim(); //创作日期
  return {
    name,
    author,
    imgurl,
    publishDate,
  };
}

async function getBook() {
  const links = await getBooksListUrl(); //详情页地址
  const prom = links.map((e) => {
    return getBookDetail(e);
  });
  return Promise.all(prom);
}

async function saveDB() {
  const book = await getBook();
  console.log(book);
  await Book.bulkCreate(book);
  console.log("书籍抓取成功");
}

saveDB();

至此就全部结束了,大家可以通过npm进行安装与学习,总之node爬虫还是比较方便的,存入数据库后,我们可以随心所欲的使用,注意不要盈利,那么问题来了,为什么一说爬虫就是豆瓣呢?

相关推荐
时差95316 分钟前
【面试题】Hive 查询:如何查找用户连续三天登录的记录
大数据·数据库·hive·sql·面试·database
让学习成为一种生活方式18 分钟前
R包下载太慢安装中止的解决策略-R语言003
java·数据库·r语言
秋意钟44 分钟前
MySQL日期类型选择建议
数据库·mysql
Dxy12393102161 小时前
python下载pdf
数据库·python·pdf
xiaoxiongip6662 小时前
HTTP 和 HTTPS
网络·爬虫·网络协议·tcp/ip·http·https·ip
~甲壳虫2 小时前
说说webpack中常见的Plugin?解决了什么问题?
前端·webpack·node.js
桀桀桀桀桀桀2 小时前
数据库中的用户管理和权限管理
数据库·mysql
~甲壳虫3 小时前
说说webpack中常见的Loader?解决了什么问题?
前端·webpack·node.js
~甲壳虫3 小时前
说说webpack proxy工作原理?为什么能解决跨域
前端·webpack·node.js
superman超哥3 小时前
04 深入 Oracle 并发世界:MVCC、锁、闩锁、事务隔离与并发性能优化的探索
数据库·oracle·性能优化·dba