如何結合Node和Puppeteer做網絡爬蟲

相信大家都聽說過爬蟲,我們也聽說過Python是可以很方便地爬取網絡上的圖片,但是奈何本人不會Python,就只有通過Node來實踐一下了。

01 前言

何謂爬蟲

其實爬蟲用很官方的語言來描述就是“自動化瀏覽網絡程序”,我們不用手動去點擊、去下載一些文章或者圖片。大家或許用過搶票軟件,其實就是不斷地通過軟件訪問鐵路官方的接口,達到搶票的效果。但是,這類搶票軟件是違法的。

那麼怎麼判斷爬蟲是不是違法呢?關於爬蟲是否非法其實沒有很明確的說法,一直都是中立的態度。爬蟲是一種技術,技術本身沒有違法的。但是你使用這種技術去爬取不正當的信息、有版權的圖片等用於商用,那麼你就是違法了。其實我們只要在使用爬蟲技術的時候不要去爬個人隱私信息,不要爬取有版權的圖片,最重要的是信息不要用於商業化的行爲,爬蟲不得干擾網站的正常運行等。

說了這麼多其實就是要大家謹慎使用這一項技術。

怎麼爬

我查了一下資料,使用Node做爬蟲的話其實有很多的途徑,很多人比較喜歡的就是使用cheerio以及request來爬取。但是我也發現了一個比較好用的工具就是puppeteer,這一項技術是谷歌官方提供的一款工具。它其實就是把人來做的事情變成了調用接口來實現。看了一下官方的文檔,主要可以實現以下的功能:puppeteer官方文檔

  • 生成頁面的屏幕截圖和PDF。
  • 爬取SPA(單頁應用程序)並生成預渲染的內容(即“ SSR”(服務器端渲染))。
  • 自動執行表單提交,UI測試,鍵盤輸入等。
  • 創建最新的自動化測試環境。使用最新的JavaScript和瀏覽器功能,直接在最新版本的Chrome中運行測試。
  • 捕獲站點的時間線跟蹤以幫助診斷性能問題。
  • 測試Chrome擴展程序。

同時也看了一些同學的評價,覺得這個東西是非常的amazing啊!雖然我還沒有深入去了解全部的API,但是也算是懂得大概的流程。大家如果官方的文檔看不懂的話可以去B站看一下基本的介紹,puppeteer系列教程

02 安裝過程

puppeteer安裝

關於這個安裝的事情真的是非常的頭疼,搞了許久才安裝成功。原因就是高高的圍牆使得城內的人出不去。所以我們只有換另外一種方法來安裝了。

我們直接npm安裝的過程默認是要下載瀏覽器的,我就是在這裏一直卡住然後報錯,試了好幾次都是這樣。經過網友們的介紹我們是可以不用在安裝puppeteer的時候下載瀏覽器的,我們可以事後纔去下載

env PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true npm i puppeteer

我們這樣就可以成功安裝puppeteer了,接下來我們就要去手動安裝瀏覽器了。那麼我們要去哪裏下載呢?我要手動下載

這裏面非常多的版本號,看了網上的教程我們要選擇合適的版本號(不知道隨便下載一個可不可以),我們回到項目的根目錄下面node_modules/puppeteer/package.json這個目錄,查看一下我們的瀏覽器版本是多少。

我這裏就是現實737027的版本號,我們就去手動下載這個瀏覽器就可以了。大家可以根據自己的版本進行下載。

瀏覽器引用

我們光安裝了之後還不行,還要進行瀏覽器的引入。這個也是非常的頭疼,看了好多的教程都不可以。可能是他們的系統不一樣,在這裏折騰很久都想放棄了。還好有這篇文章解決了我的問題,我知道是路徑有誤但我不知道怎麼寫。

瀏覽器下載之後我們就解壓放到根目錄下面,與package.json同級。然後我們在根目錄下新建一個index.js文件。

const puppeteer = require("puppeteer");
const fs = require("fs");
const request = require("request");
const path = require("path");
//配置路徑,關鍵!
const pathToExtension = require("path").join(
    __dirname,
    "./chrome-win/chrome.exe"
  );

最後我的項目目錄:

03 選擇網站

我們都設置好了之後我們就開始選取一個網站進行測試了,我這裏就選擇了這個來爬取圖片。

其實我們知道萬物皆可爬,只要分析對了就好。前端最熟悉不過的F12走一波就好。看了一下大概結構是長這樣的,準備好了之後開始擼碼。

反手一寫(CV)就出來這樣的代碼。

const puppeteer = require("puppeteer");
const fs = require("fs");
const request = require("request");
const path = require("path");
let i = 2;//頁數
async function netbian(i) {
  const pathToExtension = require("path").join(
    __dirname,
    "./chrome-win/chrome.exe"
  );
  const browser = await puppeteer.launch({
    headless: false,
    executablePath: pathToExtension,
  });
  const page = await browser.newPage();
  await page.goto(`http://pic.netbian.com/4kfengjing/index_${i}.html`);//爲了方便從第二頁開始
  let images = await page.$$eval("ul>li>a>img", (el) =>//圖片節點,API可查看官方介紹
    el.map((x) => "http://pic.netbian.com" + x.getAttribute("src"))//獲取圖片的src地址
  );
  mkdirSync(`./images`); // 存放目錄
  for (m of images) {
    await downloadImg(m, "./images/" + new Date().getTime() + ".jpg");
  }
  
  netbian(++i);//下一頁,具體結束頁可以自己限制
  // 關閉
  await browser.close();
}
netbian(i);//這裏執行

// 同步創建目錄
function mkdirSync(dirname) {
  if (fs.existsSync(dirname)) {
    return true;
  } else {
    if (mkdirSync(path.dirname(dirname))) {
      fs.mkdirSync(dirname);
      return true;
    }
  }
  return false;
}

// 下載文件 保存圖片
async function downloadImg(src, path) {
  return new Promise(async function (resolve, reject) {
    let writeStream = fs.createWriteStream(path);
    let readStream = await request(src);
    await readStream.pipe(writeStream);
    readStream.on("end", function () {
      console.log("文件下載成功");
    });
    readStream.on("error", function () {
      console.log("錯誤信息:" + err);
    });
    writeStream.on("finish", function () {
      console.log("文件寫入成功");
      writeStream.end();
      resolve();
    });
  });
}

03 開始爬取

我們直接在根目錄運行node index.js就可以了。執行之後我們發現多了一個images目錄,裏面就是我們的圖片了。

04 小結

其實關於puppeteer的使用還有很多,這裏我只是介紹了爬蟲是怎麼用的而已。正如我們操作瀏覽器一樣,我們也可以使用對應的API來實現,本人也是剛開始,後面還要慢慢去探討這一項技術。我們其實不能保證網站的結構不改變,其實改變了我們就跟着變就好。

項目代碼:github倉庫

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章