本文來自網易雲社區html
做者:唐釗前端
最近在看 node 爬蟲相關的一些東西,我記得仍是好久之前經常使用的 node 爬蟲工具仍是 superagengt+cherrio,他們的思路是經過發起 http 請求而後截取 respone 的內容,可是隨着前端mvvm等框架的盛行,如今更多的內容是異步加載了,因此經過這種傳統的爬蟲方式已經很難抓取到咱們想要的內容了,那麼Puppeteer又有什麼亮點呢?接下來咱們詳細介紹一下這個由 google 官方團隊維護的大殺器!node
Puppeteer是一個Node庫,由Chrome官方團隊進行維護,提供接口來控制headless Chrome。Headless Chrome是一種不使用Chrome來運行Chrome瀏覽器的方式。簡單的來講就是一個運行在命令行中的 chrome,咱們能夠經過代碼來實現咱們常規的瀏覽器瀏覽網頁的功能。這樣就能保證咱們拿到的內容和正常經過瀏覽器查看的是一毛同樣的!git
利用網頁生成PDF、圖片github
爬取SPA應用,並生成預渲染內容(即「SSR」 服務端渲染)golang
能夠從網站抓取內容chrome
自動化表單提交、UI測試、鍵盤輸入等npm
幫你建立一個最新的自動化測試環境(chrome),能夠直接在此運行測試用例api
捕獲站點的時間線,以便追蹤你的網站,幫助分析網站性能問題瀏覽器
接下來咱們經過一些簡單的示例來看一下它的使用
安裝仍是常規的流程,經過yarn或npm來完成。只需運行下面的命令:
yarn add pupeeter//ornpm i -S puppeteer
const puppeteer = require("puppeteer"); //引入 puppeteer(async() => { /*經過 launch 生成一個’瀏覽器‘實例, option 中的 headless 是個布爾值,若是是 false 的話你就會看到一個瀏覽器從打開,到完成你整個任務的全過程, 默認是 true,也就是在後臺自動完成你的任務 */ const browser = await puppeteer.launch({ headless: false }); //打開一個新的標籤頁 const page = await browser.newPage(); //跳轉到咱們想要的地址去 await page.goto("http://www.hockor.com/"); //默認打開的視口大小是800X600 ,咱們能夠經過以下代碼來設置窗口的大小, await page.setViewport({ width:1920, height:1080 }) //經過screenshot方法完成截屏,而且保存在指定的 path 中 await page.screenshot({ path: "nba.png" }); //最後關閉整個‘瀏覽器‘ browser.close(); })();
過程以下:
上面咱們展現了 puppeteer一個基礎的 demo 完整實例,可是它更強大的地方還有不少,不只支持在網頁上點擊,還能夠填寫表單,讀取數據。你們能夠去官方 api 查看,傳送連接
接下來開始咱們下一個 demo,這個示例咱們完成一個在搜索引擎中爬取咱們想要的圖片並保存到本地的功能。來更進一步的瞭解這個強大的工具。
咱們的任務是在搜狗圖片中爬取關鍵詞爲「NBA」的圖片,而且保存在咱們當前的 imgs 目錄下。
那麼核心的關鍵點就在於輸入咱們的關鍵詞而且跳轉到對應的列表頁面,而後爬取內容中全部的 img 標籤,並將其保存在咱們制定的目錄中。接下來咱們詳細剖析。
經過查看Puppeteer API,能夠找到定義點擊的函數和聚焦的函數:
page.click(selector[, options]) page.focus(selector);
以上selector 一個選擇器來指定要點擊的元素。若是多個元素知足,那麼默認選擇第一個。 這不正好知足了咱們前面的邏輯,輸入框聚焦和點擊,那麼怎麼輸入關鍵詞呢?
For finer control, you can use keyboard.down, keyboard.up, and keyboard.sendCharacter to manually fire events as if they were generated from a real keyboard.
能夠看到咱們能夠經過 page.keyboard.sendCharacter 來輸入咱們本身的文字
正好,這樣子咱們就知足了咱們前期的條件,那麼完整的代碼以下
const puppeteer = require("puppeteer"); (async ()=>{ const brower = await puppeteer.launch(); const page = await brower.newPage(); await page.goto("http://pic.sogou.com/"); await page.setViewport({ width:1920, height:1080 }) //上面的代碼和以前是同樣的,不一樣是下面幾句 // await page.focus("#form_querytext"); await page.keyboard.sendCharacter("nba"); await page.click("#searchBtn") await page.waitFor(1000); //監聽頁面 load 完成 page.on('load',async ()=>{ console.log("page loaded"); const srcs = await page.evaluate(()=> { const images = document.querySelectorAll("img.img-hover"); return Array.prototype.map.call(images,img=>img.src) }) //遍歷圖片而且保存 srcs.forEach(async (src)=> { console.log(src) const ext = path.extname(src) ? path.extname(src):".jpg"; const file = path.join('./imgs',`${Date.now()}${ext}`) http.get(src,res=>{ res.pipe(fs.createWriteStream(file)).on('finish',(err)=>{ if(err){ console.log(err) } else { console.log("done") } }) }) }) await brower.close() }) })()
咱們能夠看到上面的流程就像咱們正常瀏覽網頁同樣,而不是之前那種在 http response 中去抓取內容,這樣子對於如今的不少懶加載頁面或者前端渲染來說咱們都能成功的爬取到咱們想要的內容。
更多的官方 demo 例子咱們能夠去https://try-puppeteer.appspot.com/編輯查看。
目前 puppeteer在爬蟲和前端自動化測試上使用也日益增大,你們能夠去官方 API 文檔查看它的更多功能!你們也能夠結合本身的需求/業務場景,充分挖掘Puppeteer功能。
網易雲免費體驗館,0成本體驗20+款雲產品!
更多網易研發、產品、運營經驗分享請訪問網易雲社區
相關文章:
【推薦】 從golang的垃圾回收提及(下篇)