puppeteer優化小技巧

Puppeteer是一個Node庫,它提供了高級API來經過DevTools協議控制Chromium或Chrome。javascript

經過puppeteer咱們能夠編寫腳本模擬瀏覽器的相關行爲,實現如下功能:java

  • 網頁截圖並保存爲圖片或 pdf 。
  • 模擬表單提交,鍵盤輸入,按鈕點擊,滑塊移動等dom操做。
  • 實現UI的自動化測試。
  • 做爲抓包工區對網頁性能進行調試和分析。
  • 編寫定製化爬蟲,解決傳統HTTP抓取SPA頁面難以處理異步請求的問題。

在使用puppeteer實現以上功能,咱們經過幾個小技巧提高pupeteer程序的效率。git

過濾請求

當咱們使用puppeteer對頁面異步渲染的dom結構進行解析時,每每須要等待頁面完成渲染完成以後,才能使用腳本進行操做。但頁面渲染過程當中也包含了許多靜態資源如:圖片/音頻/視頻/樣式文件等。此時咱們能夠經過page.setRequestInterception方法,對網頁請求進行過濾,攔截靜態資源的請求,加快頁面渲染速度。代碼示例以下:github

// 開啓請求攔截功能
    page.setRequestInterception(true);
    
    page.on('request', async req => {
        // 根據請求類型過濾
        const resourceType = req.resourceType();
        if (resourceType === 'image') {
            req.abort();
        else {
            req.continue();
        }
    });
複製代碼

推薦攔截的請求類型:chrome

const blockedResourceTypes = [
    'image',
    'media',
    'font',
    'texttrack',
    'object',
    'beacon',
    'csp_report',
    'imageset',
];

const skippedResources = [
    'quantserve',
    'adzerk',
    'doubleclick',
    'adition',
    'exelator',
    'sharethrough',
    'cdn.api.twitter',
    'google-analytics',
    'googletagmanager',
    'google',
    'fontawesome',
    'facebook',
    'analytics',
    'optimizely',
    'clicktale',
    'mixpanel',
    'zedo',
    'clicksor',
    'tiqcdn',
];
複製代碼

代理請求

除了過濾請求以外,咱們也可用代理網頁渲染過程當中發出的請求。在某些爬蟲項目達到不被髮爬的目的,代碼示例以下:canvas

page.on('request', async req => {
    // 代理請求
    const response = await fetch({
        url: req.url(),
        method: req.method(),
        headers: req.headers(),
        body: req.postData(),
        proxy: getProxyIp(),
        resolveWithFullResponse: true,
    });
    // 響應請求
    req.respond({
        status: response.statusCode,
        contentType: response.headers['content-type'],
        headers: response.headers || req.headers(),
        body: response.body,
    });
});
複製代碼

複用browser

使用puppeteer.connectpuppeteer.launch啓動一個瀏覽器實例要快不少(參考),因此當咱們須要開啓多個broswer實例時,能夠經過緩存wsEndpoint來達到複用的目的,代碼實例以下:api

let wsEndpoint = await cache.get(Parser.WS_KEY);
let broswer;
try {
    browser = !wsEndpoint
        ? await puppeteer.launch(config)
        : await puppeteer.connect({
              browserWSEndpoint: this.wsEndpoint,
          });
} catch (err) {
    browser = await puppeteer.launch(config);
} finally {
    wsEndpoint = this.browser.wsEndpoint();
    await cache.set(Parser.WS_KEY, 60 * 60 * 1000, this.wsEndpoint);
}
複製代碼

禁用瀏覽器多餘功能

puppeteer爲咱們提供了完善瀏覽器環境,但實際開發中,有不少默認開啓的功能是項目自己不須要的,此時咱們能夠設置瀏覽器啓動參數來禁用額外的功能:瀏覽器

puppeteer.launch({
        args: [
            '--no-sandbox',                    // 沙盒模式
            '--disable-setuid-sandbox',        // uid沙盒
            '--disable-dev-shm-usage',         // 建立臨時文件共享內存
            '--disable-accelerated-2d-canvas', // canvas渲染
            '--disable-gpu',                   // GPU硬件加速
        ]
    });
複製代碼

參考資料

相關文章
相關標籤/搜索