node.js实现爬虫

Node.js实现爬虫

什么是爬虫?

 网络爬虫(又被称为网页蜘蛛,网络机器人,在FOAF社区中间,更经常的称为网页追逐者),是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本。另外一些不常使用的名字还有蚂蚁、自动索引、模拟程序或者蠕虫。大多数爬虫都是按“发送请求”-“获取页面”-“解析页面”-"抽取并储存内容"这样的流程来进行,这其实也是模拟了我们使用浏览器获取网页信息的过程。

所需要的模块

  • puppeteer,下载puppeteer模块,用于Node.js爬虫
  • mongoose,下载mongoose模块,用于连接数据库,将爬取的数据传入数据库中。
//下载puppeteer
npm install puppeteer
//下载mongoose
npm install mongoose

正式开始

 在这里我们爬取豆瓣的电影信息来进行测试哦!
在这里插入图片描述
 看到上面电影信息列表,是不是有种爬取列表信息的冲动?好,我们先打开开发者选项,查看该列表信息。
在这里插入图片描述
 我们可以看到每个li标签的data-xxx属性中都带有该电影项的信息,我们通过获取到该信息,并且将其输出到某界面或存储到数据库中,这就实现了爬虫多种用途的一小部分。话不多说我们来上代码。

使用爬虫获取界面电影列表的信息

//引入puppeteer模块
const puppeteer = require('puppeteer');

//爬取热门电影信息,的网址
const url = 'https://movie.douban.com/cinema/nowplaying/beijing/';
//因为要请求信息,这里我们加入async
module.exports = async () => {
  //1. 打开浏览器
  const browser = await puppeteer.launch({
    args: ['--no-sandbox'],
    // headless: false    //以无头浏览器的形式打开浏览器,没有界面显示,在后台运行的
  });
  //2. 创建tab标签页
  const page = await browser.newPage();
  //3. 跳转到指定网址
  await page.goto(url, {
    waitUntil: 'networkidle2'  //等待网络空闲时,在跳转加载页面
  });
  //4. 等待网址加载完成,开始爬取数据
  //开启延时器,延时2秒钟在开始爬取数据
  await timeout();
  
  let result = await page.evaluate(() => {
    //对加载好的页面进行dom操作
    //所有爬取的数据数组
    let result = [];
    //获取所有热门电影的li,这里可以打开开发者选项进行标签的筛选
    const $list = $('#nowplaying>.mod-bd>.lists>.list-item');
    //这里我们只取8条数据
    for (let i = 0; i < 8; i++) {
      const liDom = $list[i];
      //电影标题
      let title = $(liDom).data('title');
      //电影评分
      let rating = $(liDom).data('score');
      //电影片长
      let runtime = $(liDom).data('duration');
      //导演
      let directors = $(liDom).data('director');
      //主演
      let casts = $(liDom).data('actors');
      //豆瓣id
      let doubanId = $(liDom).data('subject');
      //电影的详情页网址
      let href = $(liDom).find('.poster>a').attr('href');
      //电影海报图
      let image = $(liDom).find('.poster>a>img').attr('src');
      //将爬取到的数据加入进该数组中
      result.push({
        title,
        rating,
        runtime,
        directors,
        casts,
        href,
        image,
        doubanId
      })
    }
    
    //将爬取的数据返回出去
    return result;
  })
  
  console.log(result);
  
  //遍历爬取到的8条数据
  for (let i = 0; i < result.length; i++) {
    //获取条目信息
    let item = result[i];
    //获取电影详情页面的网址
    let url = item.href;
    
    //跳转到电影详情页
    await page.goto(url, {
      waitUntil: 'networkidle2'  //等待网络空闲时,在跳转加载页面
    });
  
    //爬取其他数据
    let itemResult = await page.evaluate(() => {
      let genre = [];
      //类型
      const $genre = $('[property="v:genre"]');
  
      for (let j = 0; j < $genre.length; j++) {
        genre.push($genre[j].innerText);
      }
      
      //简介
      const summary = $('[property="v:summary"]').html().replace(/\s+/g, '');
      
      //上映日期
      const releaseDate = $('[property="v:initialReleaseDate"]')[0].innerText;
      
      //给单个对象添加两个属性
      return {
        genre,
        summary,
        releaseDate
      }
      
    })
  
    // console.log(itemResult);
    //在最后给当前对象添加三个属性
    //在evaluate函数中没办法读取到服务器中的变量
    item.genre = itemResult.genre;
    item.summary = itemResult.summary;
    item.releaseDate = itemResult.releaseDate;
    
  }
  
  console.log(result);
  
  //5. 关闭浏览器
  await browser.close();
  
  //最终会将数据全部返回出去
  return result;
}

function timeout() {
  return new Promise(resolve => setTimeout(resolve, 2000))
}

将爬取的数据存入进数据库

创建数据库连接

 在此时我们引入mongoose,进行数据库的连接。话不多说上代码。

//引入mongoose
const mongoose = require('mongoose');

module.exports = new Promise((resolve, reject) => {
  //连接数据库
  mongoose.connect('mongodb://localhost:27017/movie_list', {
    useNewUrlParser: true,
    useUnifiedTopology: true   
  });
  //绑定事件监听
  mongoose.connection.once('open', err => {
    if (!err) {
      console.log('数据库连接成功了~~');
      resolve();
    } else {
      reject('数据库连接失败:' + err);
    }
  })
})

数据库建表

//引入mongoose
const mongoose = require('mongoose');
//获取Schema
const Schema = mongoose.Schema;
//创建约束对象
const theatersSchema = new Schema({
  title: String,
  rating: Number,
  runtime: String,
  directors: String,
  casts: String,
  image: String,
  doubanId: {
    type: Number,
    unique: true
  },
  genre: [String],
  summary: String,
  releaseDate: String,
  posterKey: String,     //图片上传到七牛中,返回的key值
  createTime: {
    type: Date,
    default: Date.now()
  }
})
//创建模型对象
const Theaters = mongoose.model('Theaters', theatersSchema);
//暴露出去
module.exports = Theaters;

将爬虫爬取的数据引入数据库

//引入Theaters
const Theaters = require('../../model/theaters');

module.exports = async data => {
  
  for (var i = 0; i < data.length; i++) {
    let item = data[i];
  
    await Theaters.create({
      title: item.title,
      rating: item.rating,
      runtime: item.runtime,
      directors: item.directors,
      casts: item.casts,
      image: item.image,
      doubanId: item.doubanId,
      genre: item.genre,
      summary: item.summary,
      releaseDate: item.releaseDate,
    })
  
    console.log('数据保存成功'); 
  }
}

将子模块引入该主模块中执行

//引入数据库连接
const db = require('../db');
//引入爬虫
const theatersCrawler = require('./crawler/theatersCrawler');
//引入将爬取信息保存到数据库模块
const saveTheaters = require('./save/saveTheaters');

(async () => {

  //连接数据库
  await db;d
  //爬取数据
  const data = await theatersCrawler();
  //将爬取的数据保存在数据库中
  await saveTheaters(data);
 
})()

 
 有帮助的话就点个赞呗!

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值