如何用 Node.Js
和 Puppeteer
爬取網頁
原文:How To Scrap That Web Page With Node.Js And Puppeteer
作者:Francesco Napoletano 發表時間:2018/8/17
譯者:陳 昌茂 發表時間:2018/8/20
(轉載請註明出處)
如果你像我一樣,有時非常急切地想要抓去某個網頁,得到可讀格式的資料,或僅是需要這些資料用做其他目的。
我莊嚴發誓,我在幹壞事。(非譯者)
我在多次嘗試以後(如: Guzzle
和 BeautifulSoup
等),終於找到了最優組合方案:
- Node.js( 譯者注:採用谷歌V8引擎開發的在伺服器端執行JavaScript程式碼的跨平臺執行環境 )
- Puppeteer( 譯者注:木偶人,是谷歌瀏覽器的一個子專案,原始碼託管在 GitHub )
- 用於全天侯跑指令碼的一個黑莓派(譯者注:貌似和正文無關)
Puppeteer
是一個 Node
程式碼庫,基於 DevTools
協議,提供高階 API 自動化控制谷歌Chrome
或 Chromium
瀏覽器。Puppeteer
預設以無介面方式執行,但也可以設定為有介面方式執行谷歌Chrome
或 Chromium
瀏覽器。
這意味著什麼? 你可以在你的服務中運用一個谷歌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-core
是Puppeteer
的輕量級版本,複用本地已安裝的瀏覽器,或者連線到遠端瀏覽器。
執行環境準備好了,開幹!
直接上程式碼,知其然
在專案資料夾新建 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
的網頁!?