前端也可以爬蟲,寫于2018年08月29日,現在發布到微信公眾號申明原創。
掘金@若川 本文章鏈接:https://juejin.im/post/5b86732451882542af1c8082
1、?puppeteer
?是什么?
puppeteer
: Google
官方出品的 headless
Chrome
node
庫puppeteer
github
倉庫puppeteer
API
官方介紹:
您可以在瀏覽器中手動執行的大多數操作都可以使用
Puppeteer
完成!生成頁面的屏幕截圖和
抓取SPA
并生成預渲染內容(即“SSR
”)。
自動化表單提交,UI
測試,鍵盤輸入等。
創建最新的自動化測試環境。使用最新的JavaScript
和瀏覽器功能直接在最新版本的Chrome
中運行測試。
捕獲時間線跟蹤 您的網站,以幫助診斷性能問題。
測試Chrome
擴展程序。
2、爬取網站生成?PDF
2.1 安裝 puppeteer
# 安裝 puppeteer
# 可能會因為網絡原因安裝失敗,可使用淘寶鏡像
# npm install -g cnpm --registry=https://registry.npm.taobao.org
npm i puppeteer
# or "yarn add puppeteer"
2.2 《?React.js
小書》簡介
《
React.js
小書》簡介
關于作者@胡子大哈
這是?本關于 React.js 的?書。因為?作中?直在使?React.js
,也?直以來想總結?下??關于React.js
的?些 知識、經驗。于是把?些想法慢慢整理書寫下來,做成?本開源、免費、專業、簡單的??級別的?書,提供給社區。希望能夠幫助到更多React.js
剛??朋友。
下圖是《React.js
小書》部分截圖:
2.3 一些可能會用到的?puppeteer API
// 新建 reactMiniBook.js, 運行 node reactMiniBook.js 生成pdf
const puppeteer = require('puppeteer');
(async () => {// 啟動瀏覽器const browser = await puppeteer.launch({// 無界面 默認為true,改成false,則可以看到瀏覽器操作,目前生成pdf只支持無界面的操作。// headless: false,// 開啟開發者調試模式,默認false, 也就是平時F12打開的面版// devtools: true,});// 打開一個標簽頁const page = await browser.newPage();// 跳轉到頁面 http://huziketang.mangojuice.top/books/react/await page.goto('http://huziketang.com/books/react/', {waitUntil: 'networkidle2'});// path 路徑, format 生成pdf頁面格式await page.pdf({path: 'react.pdf', format: 'A4'});// 關閉瀏覽器await browser.close();
})();
知道這啟動瀏覽器打開頁面關閉瀏覽器主流程后,再來看幾個 API
。
const args = 1;
let wh = await page.evaluate((args) => {// args 可以這樣傳遞給這個函數。// 類似于 setTimeout(() => {console.log(args);}, 3000, args);console.log('args', args); // 1// 這里可以運行 dom操作等js// 返回通過dom操作等獲取到的數據return {width: 1920,height: document.body.clientHeight,};
}, args);
// 設置視圖大小
await page.setViewport(wh);
// 等待2s
await page.waitFor(2000);
// 以iPhone X執行。
const devices = require('puppeteer/DeviceDescriptors');
const iPhone = devices['iPhone X'];
await page.emulate(iPhone);
2.4 知道了以上這些?API
后,就可以開始寫主程序了。
簡單說下:實現功能和主流程。從上面 React.js小書
截圖來看。
1、打開瀏覽器,進入目錄頁,生成 0.React小書目錄.pdf
2、跳轉到 1.React.js簡介
頁面,獲取左側所有的導航 a
鏈接的 href
,標題。
3、用獲取到的 a鏈接數組
進行 for
循環,這個循環里主要做了如下幾件事:
3.1 隱藏左側導航,便于生成
3.2 給React.js簡介
等標題 加上序號,便于查看
3.3 設置docment.title
加上序號, 便于在頁眉中使用。
3.4 隱藏 傳播一下知識也是一個很好的選擇 這一個模塊(因為頁眉頁腳中設置了書的鏈接等信息,就隱藏這個了)
3.5 給 分頁 上一節,下一節加上序號,便于查看。
3.6 最末尾聲明下該
3.7 返回寬高,用于設置視圖大小
3.8 設置視圖大小,創建生成
4、關閉瀏覽器
具體代碼:可以查看這里爬蟲生成《React.js小書》的 pdf
每一小節的代碼
// node 執行這個文件
// 筆者這里是:
node src/puppeteer/reactMiniBook.js
即可生成如下圖:每一小節(0-46小節)的 pdf
生成這些后,那么問題來了,就是查看時總不能看一小節,打開一小節來看,這樣很不方便。
于是接下來就是合并這些 pdf
成為一個 pdf
文件。
3、合并成一個PDF文件?pdf-merge
起初,我是使用在線網站Smallpdf,合并 PDF
。合并的效果還是很不錯的。這網站還是其他功能。比如 word
轉 pdf
等。
后來找到社區提供的一個 npm
package
pdf merge。(畢竟筆者是寫程序的,所以就用代碼來實現合并了)
這個 pdf-merge
依賴 pdftk
安裝 PDFtk
Windows
下載并安裝
筆者安裝后,重啟電腦才能使用。
Debian, Ubuntu 安裝
筆者在Ubuntu系統安裝后,即可使用。apt-getinstall pdftk
使用例子
const PDFMerge = require('pdf-merge');
const files = [`${__dirname}/1.pdf`,`${__dirname}/2.pdf`,
];
// Buffer (Default)
PDFMerge(files)
.then((buffer) => {...});
// Stream
PDFMerge(files, {output: 'Stream'})
.then((stream) => {...});
// 筆者這里使用的是這個
// Save as new file
PDFMerge(files, {output: `${__dirname}/3.pdf`})
.then((buffer) => {...});
知道這些后,可以開始寫主程序了。
簡單說下主流程
1、讀取到生成的所有 pdf
文件路徑,并排序(0-46)
2、判斷下輸出文件夾是否存在,不存在則創建
3、合并這些小節的 pdf
保存到新文件 React小書(完整版)-作者:胡子大哈-時間戳.pdf
具體代碼:可以查看這里爬蟲生成《React.js小書》的 pdf
合并 pdf
的代碼
最終合并的pdf文件可供下載。百度網盤鏈接: https://pan.baidu.com/s/107WNpJqHbBPxAGsXS51u5A 提取碼: m4nd。github下載鏈接:React小書(完整版)-作者:胡子大哈。
本想著還可以加下書簽和頁碼,沒找到合適的生成方案,那暫時先不加了。如果讀者有好的方案,歡迎與筆者交流。
小結
1、 puppeteer
是 Google
官方出品的 headless
Chrome
node
庫,可以在瀏覽器中手動執行的大多數操作都可以使用 Puppeteer
完成。總之可以用來做很多有趣的事情。
2、用 puppeteer
生成每一小節的 pdf
,用依賴 pdftk
的 pdf-merge
npm
包, 合并成一個新的 pdf
文件。或者使用Smallpdf等網站合并。
3、《 React.js
小書》,推薦給大家。爬蟲生成 pdf
,應該不會對作者@胡子大哈有什么影響。作者寫書服務社區不易,盡可能多支持作者。
最后推薦幾個鏈接,方便大家學習 puppeteer
。
puppeteer入門教程
Puppeteer 初探之前端自動化測試
爬蟲生成ES6標準入門 pdf
大前端神器安利之 Puppeteer
puppeteer API中文文檔
關于
作者:常以若川為名混跡于江湖。前端路上 | PPT愛好者 | 所知甚少,唯善學。
個人博客 https://lxchuan12.cn/posts?使用?vuepress
重構了,閱讀體驗可能更好些
https://github.com/lxchuan12/blog,相關源碼和資源都放在這里,求個 star
^_^~
微信交流群,加我微信lxchuan12
,注明來源,拉您進前端視野交流群
下圖是公眾號二維碼:若川視野,一個可能比較有趣的前端開發類公眾號,目前前端內容不多
往期文章
工作一年后,我有些感悟(寫于2017年)
高考七年后、工作三年后的感悟
面試官問:JS的繼承
學習 jQuery 源碼整體架構,打造屬于自己的 js 類庫
學習underscore源碼整體架構,打造屬于自己的函數式編程類庫
學習 lodash 源碼整體架構,打造屬于自己的函數式編程類庫
學習 sentry 源碼整體架構,打造屬于自己的前端異常監控SDK
由于公眾號限制外鏈,點擊閱讀原文,或許閱讀體驗更佳,覺得文章不錯,可以點個在看呀^_^