我經常使用的puppeteer爬蟲api

本文共1451字,閱讀時間約4分鐘前端

Puppeteer是Chrome團隊出的nodejs庫(無頭瀏覽器),其中一個功能是網頁抓取(能夠做爲爬蟲使用)vue

詳細介紹請看gayhub,更新週期大約是一個月,本文是基於 v1.4.0寫的,大體api是通用的。 本文總結了Puppeteer爬蟲的主要用法。個人目標是,有了這篇文章,平常的通常爬蟲使用就不須要去看官方文檔了。node

1、安裝和使用

1.1安裝

cnpm i -S puppeteer 用cnpm安裝沒有試過報錯,默認會下載puppeteer配套版本的Chromium。git

1.2 使用

const puppeteer = require('puppeteer');

(async () => {
   const browser = await puppeteer.launch({
    headless: false, //默認爲true(無頭),不顯示瀏覽器界面
    slowMo :200, //減速顯示,有時會做爲模擬人操做特地減速
    devtools: true //顯示開發者工具。頁面寬高默認800*600,把開發者工具顯示再隱藏頁面會佔滿屏幕,有沒有大佬解釋下?
  });
  //生成Page對象
  //const page = await browser.newPage();//官網寫法:一打開瀏覽器會打開兩個tab,第二個纔是你正在操做的tab
  const page = (await browser.pages())[0]; //這是個人寫法,只有一個tab
  await page.goto('https://www.juejin.com'); //跳轉到掘金
 //請開始你的表演...

  await browser.close(); //關閉瀏覽器
})();
複製代碼

puppeteer基本上每一個操做都會返回一個Promise,記得要用await接收下一步的操做。github

puppeteer上也提供了一些第三方寫的爬蟲demo,不過感受封裝得有點多,先不玩。面試

2、基本用法

2.1 調整頁面

頁面寬高默認800*600,我以爲過小。我通常都會先初始化頁面大小。正則表達式

和上面說的同樣,這只是初始化的時候的大小,當打開再隱藏開發者工具後,頁面就會佔滿全屏了,不知道這是否是bug。npm

await page.setViewport({
    width: 1280,
    height: 800
  });
複製代碼

2.2 模擬輸入和點擊

目測底層是用document.querySelector()api

await page.type(selector, 'Hello puppeteer'); //找到對應的選擇器而後填充值。若是以前設置了slowMo會看到像人打字同樣,值是一個一個填進<input/>
await page.click(selector); //模擬點擊,這對傳統異步分頁(url沒有分頁參數)頗有用,selector定在下一頁的標籤上
複製代碼

2.3 iframe處理

若是網頁內有用iframe等標籤,這時page對象是沒法讀取<iframe>裏面的內容的,須要用到page.frames()。返回一個Frame對象數組。 一般iframe會有name屬性,判斷name屬性能夠快速獲取單個Frame對象的內容。數組

let iframe = await page.frames();
iframe.find(f => f.name() === 'name')
複製代碼

2.4 waitFor函數

waitFor函數是簡寫,Page和Frame對象都有。我只會用如下兩種方式,剩下了請大佬指點一下。

爲了簡化,Page和Frame對象都有的api,我不會再特地說明,會在代碼中直接體現。

await iframe.waitFor('.contain .item') //在<iframe>中等待'.contain .item'的節點出現,阻塞結束(ps:優先使用,有時200ms我是等不起的)
await page.waitFor(200)//頁面等待200ms
複製代碼

2.5 selector和emulate

爲何要合在一點寫呢?由於確實有一個組合的api叫eval

先分開說說吧。

2.5.1 selector

目測底層是用document.querySelector()和document.querySelectorAll()。熟悉這兩個api的人應該很容易上手。

//ps:較少用
page.$(selector) // document.querySelector()
iframe.$$(selector) // document.querySelectorAll(), $$是All的意思
複製代碼

2.5.2 emulate

這裏首先要有個概念,puppeteer爬蟲解析dom在瀏覽器,這個api的實參在瀏覽器中。因此能夠在這個函數內進行dom操做,同時本地的node api是沒法在這裏運行的,運行console.log(global)會報錯。

舉個栗子:在函數內有console.log('按f12,我出如今瀏覽器的console中,並不在node命令行')

你會發現node命令行看不到這句話,而在Chromium的console中看見。所以你應該理解他的運行環境是當前網站,而不是你本地的node。

//ps:更少用
await page.evaluate(el => {
    //喜聞樂見的dom操做
})
await iframe.evaluate(el => {
    //請開始你的表演
    console.log('按f12,我出如今瀏覽器的console中,並不在node命令行')
})
複製代碼

2.5.3 真正的主角 $eval$$eval

上面的兩個api一塊兒用就變成了eval,我最經常使用的api之一。一個api頂上面兩個,集中一塊兒寫,舒服。

const result = await page.$eval(selector, el => {
    //若是須要賦值要返回Promise
    return new Promise(resolve => {
        //...一波騷操做
        //能夠用Dom api啦
        reslove(obj)
    })
});
await iframe.$$eval(selector, el => {...});
複製代碼

2.6 監聽事件

上文說過在page.evaluate中用console是不能在node命令行打印出來的,不過有了監聽事件就能夠改變這個規則了。也能夠在監聽事件裏面作容錯處理。

page.on('console', msg => {
    console.log(msg);
});
複製代碼

我的以爲若是打印dom的話,仍是看瀏覽器的console比較好,直觀。

//監聽瀏覽器報錯
page.on('pageerror', pageErr => {
    console.log(pageErr);
});
//監聽node報錯
page.on('error', err => {
    console.log(err);
});
複製代碼

3、假裝移動端

const devices = require("puppeteer/DeviceDescriptors");
const iPhone = devices["iPhone 6"];
...
await page.emulate(iPhone);
複製代碼

更多設備能夠查看這裏

以上就是我要介紹的puppeteer爬蟲api。


安利兩本書,一本是老姚的正則表達式pdf版說得很詳細,確實頗有用,雖然我已經忘了一大半了(╯﹏╰);另外一本是 Web 前端面試指南與高頻考題解析小冊子,內容基礎又豐富,但願我能夠找個機會實踐一下。

下面我要說說正事

小弟不才,17年軟件工程畢業生,熟悉vue寫過兩個公司項目。目前已離職,座標廣州,求大佬們收留。

相關文章
相關標籤/搜索