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爬虫还是比较方便的,存入数据库后,我们可以随心所欲的使用,注意不要盈利,那么问题来了,为什么一说爬虫就是豆瓣呢?

相关推荐
Patrick在香港7 小时前
Claude 工具调用返回空:8 次失败里只有 1 次状态码不对,其余全带 200
爬虫·python·api·claude·香港
十二同学啊9 小时前
向量数据库:从核心原理到 RAG 与 Java 实战
数据库
蓝速科技9 小时前
会议室门牌公告通知发布选型与落地指南丨蓝速科技
大数据·运维·数据库·人工智能·科技
一 乐12 小时前
二手交易平台|基于springboot + vue二手交易平台(源码+数据库+文档)
java·数据库·vue.js·spring boot·小程序
SelectDB12 小时前
同等资源下 Apache Doris 4.2 vs StarRocks 4.1.1:1TB SSB 与 TPC-H 性能实测
大数据·数据库·数据分析
这个DBA有点耶13 小时前
数据库集群与分布式架构:三条技术路线对比、金仓KES RAC实测数据与决策框架
数据库·程序员·架构
MayBaymax13 小时前
MongoDB 索引与事务
java·数据库·mongodb
SelectDB13 小时前
Doris vs ClickHouse:企业 OLAP 走向下一阶段,两种技术路线如何选择
大数据·数据库·数据分析
vx-程序开发13 小时前
【计算机毕设】django校园跑腿服务系统83141
java·数据库·vue.js·spring boot·spring·elasticsearch·django
一 乐14 小时前
养老院管理系统|基于springboot + vue养老院管理系统(源码+数据库+文档)
java·数据库·vue.js·spring boot·毕业设计