欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

node学习—数据抓取

程序员文章站 2022-07-01 10:39:13
...

一、数据抓取

部分应用中我们可能需要一些存在网页中的一些数据,此时我们不可能照着网页去一个一个敲打出来。那么数据抓取就显得尤为重要了。
我们这里通过讲解抓取 豆瓣读书 的数据,来了解什么是数据抓取。

抓取准备工具库:axioscheerio

//简单介绍cheerio的使用,类似jQuery
const cheerio = require('cheerio');
const $ = cheerio.load('<h2 class="title">Hello world</h2>');//这里可以放入网页地址

$('h2.title').text('Hello there!');//选着出需要标签的数据即可
$('h2').addClass('welcome');

1.抓取豆瓣网页

下载依赖npm i axios cheerio

//fetchBooks.js
const axios = require("axios").default;
const cheerio = require("cheerio");
const Book = require("../models/Book");

async function getBooksHTML() {
  const resp = await axios.get("https://book.douban.com/latest");
  return resp.data;//在resp.data中是字符html数据
}

node学习—数据抓取

2、网页中寻找需求

/**
 * 从豆瓣读书中得到一个完整的网页,并从网页中分析出书籍的基本信息,然后得到一个书籍的详情页链接数组
 */
async function getBookLinks() {
  const html = await getBooksHTML();//拿到html
  const $ = cheerio.load(html);
  const achorElements = $("#content .grid-12-12 li a.cover");//考虑到当前总页面不方便拿到各数据,所以拿到书的详情页地址
  const links = achorElements
    .map((i, ele) => {
      const href = ele.attribs["href"];
      return href;
    })
    .get();
  return links;
}

node学习—数据抓取

node学习—数据抓取

/**
 * 从豆瓣读书中得到一个完整的网页,并从网页中分析出书籍的基本信息,然后得到一个书籍的详情页链接数组
 */
async function getBookLinks() {
  const html = await getBooksHTML();
  const $ = cheerio.load(html);
  const achorElements = $("#content .grid-12-12 li a.cover");
  const links = achorElements
    .map((i, ele) => {
      const href = ele.attribs["href"];
      return href;
    })
    .get();
  return links;
}

最终拿到当面页面所有书的详情页地址
node学习—数据抓取

3、利用地址进入详情页拿到数据

/**
 * 根据书籍详情页的地址,得到该书籍的详细信息
 * @param {*} detailUrl
 */
async function getBookDetail(detailUrl) {
  const resp = await axios.get(detailUrl);//请求书籍地址
  const $ = cheerio.load(resp.data);//拿到html
  const name = $("h1").text().trim();
  const imgurl = $("#mainpic .nbg img").attr("src");//拿到书籍图片地址
  const spans = $("#info span.pl");
  const authorSpan = spans.filter((i, ele) => {
    return $(ele).text().includes("作者");
  });
  const author = authorSpan.next("a").text();
  const publishSpan = spans.filter((i, ele) => {
    return $(ele).text().includes("出版年");
  });
  const publishDate = publishSpan[0].nextSibling.nodeValue.trim();
  return {
    name,
    imgurl,
    publishDate,
    author,
  };
}

node学习—数据抓取

/**
 * 获取所有的书籍信息
 */
async function fetchAll() {
  const links = await getBookLinks(); //得到书籍的详情页地址
  const proms = links.map((link) => {
    return getBookDetail(link);
  });
  return Promise.all(proms);
}

/**
 * 得到书籍信息,然后保存到数据库
 */
async function saveToDB() {
  const books = await fetchAll();
  await Book.bulkCreate(books);
  console.log("抓取数据并保存到了数据库");
}

saveToDB();

4、最后

成功爬取豆瓣读书的书籍数据(事件不同,豆瓣书籍数据不同,如果爬取与本文不同,不必纠结。)

//index.js
require("./spider/fetchBooks");

node学习—数据抓取
node学习—数据抓取