Node.js实现爬虫

什么是爬虫?

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

所须要的模块

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

正式开始

 在这里咱们爬取豆瓣的电影信息来进行测试哦!

 看到下面电影信息列表,是不是有种爬取列表信息的激动?好,咱们先关上开发者选项,查看该列表信息。

 咱们能够看到每个li标签的data-xxx属性中都带有该电影项的信息,咱们通过获取到该信息,并且将其输入到某界面或存储到数据库中,这就实现了爬虫多种用处的一小部分。话不多说咱们来上代码。

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

//引入puppeteer模块const puppeteer = require('puppeteer');//爬取热门电影信息,的网址const url = 'https://movie.douban.com/cinema/nowplaying/beijing/';//因为要申请信息,这里咱们退出asyncmodule.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,进行数据库的连贯。话不多说上代码。

//引入mongooseconst 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);    }  })})

数据库建表

//引入mongooseconst mongoose = require('mongoose');//获取Schemaconst 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;

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

//引入Theatersconst 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); })()

 
 有帮忙的话就点个赞呗!