「譯」如何用 Node.Js 和 Puppeteer 爬取網頁

巴都萬發表於2019-03-03

如何用 Node.JsPuppeteer 爬取網頁

原文:How To Scrap That Web Page With Node.Js And Puppeteer

作者:Francesco Napoletano 發表時間:2018/8/17

譯者:陳 昌茂 發表時間:2018/8/20

(轉載請註明出處)

如果你像我一樣,有時非常急切地想要抓去某個網頁,得到可讀格式的資料,或僅是需要這些資料用做其他目的。

我莊嚴發誓,我在幹壞事。(非譯者)

我在多次嘗試以後(如: GuzzleBeautifulSoup 等),終於找到了最優組合方案:

  • Node.js( 譯者注:採用谷歌V8引擎開發的在伺服器端執行JavaScript程式碼的跨平臺執行環境 )
  • Puppeteer( 譯者注:木偶人,是谷歌瀏覽器的一個子專案,原始碼託管在 GitHub
  • 用於全天侯跑指令碼的一個黑莓派(譯者注:貌似和正文無關)

Puppeteer 是一個 Node 程式碼庫,基於 DevTools 協議,提供高階 API 自動化控制谷歌ChromeChromium瀏覽器。Puppeteer 預設以無介面方式執行,但也可以設定為有介面方式執行谷歌ChromeChromium瀏覽器。

這意味著什麼? 你可以在你的服務中運用一個谷歌Chrome 瀏覽器例項。是不是很酷~

下面我們一起來看下如何做。

設定執行環境

照例是開啟終端,建立專案資料夾,在剛建立的資料夾執行命令 npm init

命令執行後,資料夾中生成一個 package.json 的檔案。執行命令 npm i -S puppeteer 安裝 Puppeteer.

小小的警告:安裝 Puppeteer 過程中會下載完整版的谷歌Chromium瀏覽器到 node_modules 目錄。

不用擔心。自從 1.7.0 版後,谷歌釋出了新的 puppeteer-core 安裝包,預設不再自動下載谷歌Chromium瀏覽器。

如果你想嚐鮮,執行命令 npm i -S puppeteer-core 即可。

puppeteer-corePuppeteer 的輕量級版本,複用本地已安裝的瀏覽器,或者連線到遠端瀏覽器。

執行環境準備好了,開幹!

直接上程式碼,知其然

在專案資料夾新建 index.js 檔案,複製下述程式碼並貼上到 index.js 檔案中。

const puppeteer = require(`puppeteer`);
const URL = `https://coding.napolux.com`;

puppeteer.launch({ headless: true, args: [`--no-sandbox`, `--disable-setuid-sandbox`] }).then(async browser => {
    const page = await browser.newPage();
    await page.setViewport({width: 320, height: 600})
    await page.setUserAgent(`Mozilla/5.0 (iPhone; CPU iPhone OS 9_0_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13A404 Safari/601.1`)

    await page.goto(URL, {waitUntil: `networkidle0`});
    await page.waitForSelector(`body.blog`);
    await page.addScriptTag({url: `https://code.jquery.com/jquery-3.2.1.min.js`})

    const result = await page.evaluate(() => {
        try {
            var data = [];
            $(`h3.loop__post-title`).each(function() {
                const url = $(this).find(`a`).attr(`href`);
                const title = $(this).find(`a`).attr(`title`)
                data.push({
                    `title` : title,
                    `url`   : url
                });
            });
            return data; // 返回陣列
        } catch(err) {
            reject(err.toString());
        }
    });

    // 關閉瀏覽器
    await browser.close();

    // 記錄播客標題
    for(var i = 0; i < result.length; i++) {
        console.log(`Post: ` + result[i].title + ` URL: ` + result[i].url);
    }
    process.exit();
}).catch(function(error) {
    console.error(`No way Paco!`);
    process.exit();
});
複製程式碼

這些程式碼實現了網站爬取功能。專案完整程式碼託管在 GitHub

深挖一點點,知其所以然

上述程式碼會爬取我的部落格站點中所有帖子的標題和連結。我們修改使用者代理(UA)把爬取過程模擬成是一臺老的 iPhone 手機在瀏覽。

為便於爬取工作,我們把 jQuery 注入到網頁中,這樣就可以方便地使用 CSS 選擇器了。

我們逐行看一下程式碼:

  • 第1-2行:呼叫 Puppeteer 模組,設定將要爬取的網站地址。
  • 第4行:執行Puppeteer。請記住,我們正在非同步王國,所有的操作均是非同步的,否則就是同步操作,需等待操作結束再執行下一行程式碼。如你所見,配置引數不言自明,我們的指令碼是在無介面方式的谷歌Chromium 瀏覽器中執行的。
  • 第5-10行:瀏覽器啟動,開啟網頁,設定網頁按手機螢幕尺寸顯示,設定瀏覽器使用偽造的UA。等待頁面載入,直到 CSS 選擇器 body.blog 出現。
  • 第11行:如上所述,把 jQuery 注入到網頁中。
  • 第13-28行:我們使用 jQuery 魔法,抽取我們需要的資料。
  • 第31-37行:關閉瀏覽器。列印資料。

在專案資料夾執行命令 node index.js ,你將看到如下內容輸出:

Post: Blah blah 1? URL: https://coding.napolux.com/blah1/
Post: Blah blah 2? URL: https://coding.napolux.com/blah2/
Post: Blah blah 3? URL: https://coding.napolux.com/blah3/
複製程式碼

(執行命令 node index.js ,譯者看到如下內容輸出)

Post: How to scrap that web page with Node.js and puppeteer URL: https://coding.napolux.com/how-to-scrap-web-page-nodejs-puppeteer/
Post: How to find ideas for beer money? URL: https://coding.napolux.com/how-to-find-ideas-for-beer-money/
Post: This is the kind of automation I like! URL: https://coding.napolux.com/this-is-the-kind-of-automation-i-like/
Post: Some tips from when you work from home URL: https://coding.napolux.com/some-tips-from-when-you-work-from-home/
Post: How to find a cofounder for your startup URL: https://coding.napolux.com/how-to-find-a-cofounder-for-your-startup/
Post: Software Industry VS anything else URL: https://coding.napolux.com/software-industry-vs-anything-else/
Post: Some of my GitHub repositories URL: https://coding.napolux.com/some-of-my-github-repositories/
Post: How to use Docker for easy and fast WordPress development URL: https://coding.napolux.com/how-to-use-docker-for-wordpress-development/
複製程式碼

文章摘要說明

歡迎來到爬蟲世界。比你預想的簡單,對不對?網頁爬取是一個有爭議的事情,請記住只爬取獲得授權的網站。

可以爬取你的網站嗎?作為網站的主人,我沒有授權你這麼做

給你留個作業練手:如何爬取使用了 AJAX 的網頁!?

相關文章