2019年11月25日

Google Apps Script 網頁爬蟲麻煩事交給 Cheerio 解決,輕鬆解析 HTML 與 XML

Google Apps Script 網頁爬蟲麻煩事交給 Cheerio 解決,輕鬆解析 HTML 與 XML

Wayne Fu 0 A+
google-apps-script-parse-html-cheerio.jpg-Google Apps Script 網頁爬蟲麻煩事交給 Cheerio 解決,輕鬆解析 HTML 與 XML之前用 Google Apps Script(簡稱 GAS)製作網頁爬蟲程式,為了解析 HTML 與 XML 分別寫了兩篇心得:


其實前端環境用 jQuery 等函式庫處理 DOM 非常方便快速,習慣之後在後端處理 DOM 架構就會覺得很痛苦,要嘛想辦法自己做輪子,要嘛得學習駕馭別人另外做的變形輪子,如果後端也有 jQuery 可以用就好了。

有讀者留言提到 jsdom、cheerio 等關鍵字,這些都是 node.js 環境下用來處理 DOM 的 jQuery-like(仿 jQiery)模組。找了一下發現有國外網友做出用於 GAS 的 cheerio 版本,用了之後簡直是雨過天晴,後端也可以跟前端一樣輕鬆了,請見本篇 cheerio 的使用心得整理。



一、Cheerio 使用說明


1. 官網

首先這是 cheerio 的 node.js 官網:


這裡有官方詳細的介紹、操作說明,以及 Github 網址。

由於全部都是英文,而且跟本篇主旨 GAS 環境沒有任何關係,可以隨意看看就好。


2. 說明書

如果是英文苦手,可以閱讀這篇的簡中翻譯:


基本上如果會 jQuery 的話,不用看說明也會操作,基本常用的指令是一模一樣的。

但 cheerio 畢竟不等於 jQuery,如果有哪些 jQuery 操作方式不確定 cheerio 是否也有,就可以來這個網頁搜尋一下用法。



二、GAS 安裝 Cheerio


1. GAS 的 Cheerio 模組

在網路上找到 2 個 GAS 的 Cheerio 模組:

  1. cheerio-gasify
  2. cheeriogs

基本上第 1 個是原始版本,第 2 個是被 fork 之後的衍生版本,從 readme 說明來看也許功能比較強。

第 1 個 GAS 安裝說明完全沒有,第 2 個有 GAS 的安裝說明。然而結論是,測試的結果 2 個安裝後都無法直接使用。

經過多方測試後,第 1 個有找到解決方法,第 2 個找不出來,以下來看我怎麼調整第 1 個原始模組。


2. 安裝 cheerio-gasify

google-apps-script-parse-html-cheerio-1.png-Google Apps Script 網頁爬蟲麻煩事交給 Cheerio 解決,輕鬆解析 HTML 與 XML

首先按照第 2 個的安裝說明,先在 Google Drive 新增一個 GAS 專案,然後點選單上的「資源」→「程式庫」


google-apps-script-parse-html-cheerio-2.jpg-Google Apps Script 網頁爬蟲麻煩事交給 Cheerio 解決,輕鬆解析 HTML 與 XML

  • A:貼上前面第 1 個版本提供的 project key 字串 MU756IKHJ2hAYP1glQmzgA4ZBvzIux02r
  • B:版本選擇 cheerio@0.19.0
  • 按「儲存」即可


3. 修改呼叫函數字串

google-apps-script-parse-html-cheerio-3.jpg-Google Apps Script 網頁爬蟲麻煩事交給 Cheerio 解決,輕鬆解析 HTML 與 XML

上圖是官網提供的範例程式碼,但怎麼樣都無法執行,使用除錯模式後找到了原因,官網呼叫的函數 "cheerio_gasify" 並不存在,從偵錯畫面可看到只有 "cheeriogasify" 這個函數,所以應該是官網說明書的誤植。

把呼叫函數改成 cheeriogasify 後果然就能正常執行了!


2021.1.26 補充:現在 GAS 若使用新版介面,將無法輸入「project key」,改而必須輸入「Script ID」,那麼可改用另一個 Github 專案:
  • cheerio for Google Apps Script
  • 輸入 Script ID:1ReeQ6WO8kKNxoaA_O0XEQ589cIrRvEBA9qcWpNqdOP17i47u6N9M5Xh0
  • 選擇最新版本
  • 呼叫函數使用 Cheerio



三、操作範例


1. HTML

直接拿第 2 個版本的程式碼,但改用原始版本的模組,來當作 HTML 範例程式碼:

function html_test() {
var cheerio = cheeriogasify.require('cheerio'),
response = UrlFetchApp.fetch("https://en.wikipedia.org"),
$ = cheerio.load(response.getContentText());

Logger.log($('#mp-right').text());
Logger.log($('p').first().text());
}

可自行測試看看,很方便就能用 jQuery 取得需要的 HTML 內容字串。


2. XML

之前這篇「Google Apps Script 使用 XmlService 解析 XML 要注意的地方」可看到,為了解析 XML 得瞭解一些複雜概念,現在使用 cheerio 什麼都不用懂,就像在操作 HTML 一般。

以下把之前 XmlService 的操作程式碼,直接改用 cheerio,真是簡單太多了:

function xml_test() {
var cheerio = cheeriogasify.require('cheerio'),
response = UrlFetchApp.fetch("https://www.youtube.com/feeds/videos.xml?playlist_id=UUgxXuXHJ4VwovSTvDiWlzZQ"),
$ = cheerio.load(response.getContentText()),
entries = $("entry"),
entry1 = entries.eq(0);

Logger.log(entry1.children("yt\\:videoId").text());
Logger.log(entry1.find("author name").text());
}

很方便就取得第一則影片的 id 以及標題,不過紅字這裡需要特別說明一下:

  • yt:videoId這個元素使用了命名空間(namespace) "yt",不能直接用 jQuery 直覺的作法
  • 例如 $("yt:videoId") 會取不到東西,因為冒號 ":" 有特別的含意
  • 解決方法參考這篇「Explain \\: escaping colon for xml namespace pseudo」,有說明原理
  • 在冒號前面加上轉譯符號 "\\" 兩個斜線,就可以把冒號 ":" 視為字串了



四、補充


cheerio 畢竟不等於 jQuery,有些方法不存在,這裡補充可能會用到的 html 操作:

1. outerHtml

jQuery 可使用 prop("outerHTML") 取得元素的外部 HTML,但 cheerio 則無,提供兩種作法:

$.html(selector)

例如 $.html(".post-body")


另外一種參考「Copy the functionality of outerHTML」:

$(element).each(function() {
var $this = $(this);
console.log($.html($this));
});



2. 中文編碼

如果要輸出 html,可能會發現中文被編碼了(形成亂碼),那麼在一開始載入 html 時,需要加上參數,防止被編碼,例如:

$ = cheerio.load("這裡是 html 內容", { decodeEntities: false });


更多 Google Apps Script 相關技巧:
0 0
如這篇文章對你有幫助,歡迎「分享」到 FB、「追蹤」粉絲團、「訂閱」最新文章

沒有留言:

張貼留言注意事項:

◎ 勾選「通知我」可收到後續回覆的mail!
◎ 請在相關文章留言,與文章無關的主題可至「Blogger 社團」提問。
◎ 請避免使用 Safari 瀏覽器,否則無法登入 Google 帳號留言(只能匿名留言)!
◎ 提問若無法提供足夠的資訊供判斷,可能會被無視。建議先參考這篇「Blogger 提問技巧及注意事項」。
◎ CSS 相關問題非免費諮詢,建議使用「Chrome 開發人員工具」尋找答案。
◎ 手機版相關問題請參考「Blogger 行動版範本的特質」→「三、行動版範本不一定能執行網頁版工具」;或參考「Blogger 行動版範本修改技巧 」,或本站 Blogger 行動版標籤相關文章。
◎ 非官方範本問題、或貴站為商業網站,請參考「Blogger 免費諮詢 + 付費諮詢
◎ 若是使用官方 RWD 範本,請參考「Blogger 推出全新自適應 RWD 官方範本及佈景主題」→ 不建議對範本進行修改!
◎ 若留言要輸入語法,"<"、">"這兩個符號請用其他符號代替,否則語法會消失!
◎ 為了過濾垃圾留言,所有留言不會即時發佈,請稍待片刻。
◎ 本站「已關閉自刪留言功能」。

TOP