node.js實現爬蟲

Node.js實現爬蟲

什麼是爬蟲?

 網絡爬蟲(又被稱爲網頁蜘蛛,網絡機器人,在FOAF社區中間,更常常的稱爲網頁追逐者),是一種按照必定的規則,自動地抓取萬維網信息的程序或者腳本。另一些不常使用的名字還有螞蟻、自動索引、模擬程序或者蠕蟲。大多數爬蟲都是按「發送請求」-"獲取頁面"-"解析頁面"-"抽取並儲存內容"這樣的流程來進行,這其實也是模擬了咱們使用瀏覽器獲取網頁信息的過程。javascript

所須要的模塊

  • puppeteer,下載puppeteer模塊,用於Node.js爬蟲
  • mongoose,下載mongoose模塊,用於鏈接數據庫,將爬取的數據傳入數據庫中。
//下載puppeteer
npm install puppeteer
//下載mongoose
npm install mongoose

正式開始

 在這裏咱們爬取豆瓣的電影信息來進行測試哦!
在這裏插入圖片描述
 看到上面電影信息列表,是否是有種爬取列表信息的衝動?好,咱們先打開開發者選項,查看該列表信息。
在這裏插入圖片描述
 咱們能夠看到每一個li標籤的data-xxx屬性中都帶有該電影項的信息,咱們經過獲取到該信息,而且將其輸出到某界面或存儲到數據庫中,這就實現了爬蟲多種用途的一小部分。話很少說咱們來上代碼。html

使用爬蟲獲取界面電影列表的信息

//引入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,進行數據庫的鏈接。話很少說上代碼。java

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

 
 有幫助的話就點個讚唄!mongodb

相關文章
相關標籤/搜索