1. 程式人生 > >使用Puppeteer進行數據抓取(二)——Page對象

使用Puppeteer進行數據抓取(二)——Page對象

Go 內容 expose turn HR else 包括 div 字符串

page對象是puppeteer最常用的對象,它可以認為是chrome的一個tab頁,主要的頁面操作都是通過它進行的。Google的官方文檔詳細介紹了page對象的使用,這裏我只是簡單的小結一下。

客戶端模擬

頁面模擬設置相關函數有如下幾個,

  1. page.setViewport: 設置視圖大小
  2. page.setUserAget: 設置UserAgent
  3. page.SetCookie: 設置Cookie

另外,也可以使用emulate函數提供快捷設置,puppeteer/DeviceDescriptors還提供了常用設備的預設

const?puppeteer?=?require(‘puppeteer‘);
const?devices?=?require(‘puppeteer/DeviceDescriptors‘);|
const?iPhone?=?devices[iPhone?6];

puppeteer.launch().then(async?browser?=>?{
????const?page?=?await?browser.newPage();
????await?page.emulate(iPhone);
????await?page.goto(‘https://www.google.com‘);
????//?other?actions...
????await?browser.close();
});
除此之外
,還可以使用page.setExtraHTTPHeaders設置其它HttpHeader

?

頁面跳轉

頁面跳轉相關函數有如下幾個,

  1. page.goto(url, options)
  2. page.goBack(options)
  3. page.goForward(options)
  4. page.reload(options)

其中比較常用的是page.goto,相當於在瀏覽器中輸入了地址,然後回車。此外,也可以同通過執行js跳轉和模擬點擊link跳轉。

?

選擇

常用的元素函數選擇有:

  1. page.$(selector)
  2. page.$$(selector)

它們的功能類似於document.querySelector和document.querySelectorAll。

它們返回的對象是<Promise<?ElementHandle>>,可以用它判斷某元素是否存在,也可以對ElementHandle執行相應操作,具體在後面的ElementHandle中介紹。

另外,還有一個使用xpath的select版本。

  1. page.$x(expression)

雖然這個用的相對少點,但也還是非常有用的。

?

模擬輸入

page本身提供原始的mouse和keyboard的模擬輸入類。

  1. page.mouse
  2. page.keyboard

但同時也提供更方便快捷的模擬輸入函數

  1. page.click(selector[, options])????????在被選擇元素上模擬點擊
  2. page.type(selector, text[, options])????在被選擇的輸入框中輸入
  3. page.hover(selector)????????????????模擬鼠標移動到被選擇元素上
  4. page.select(selector, ...values)????????在被選擇元素上模擬選擇select選項
  5. page.tap(selector)????????????????????在被選擇元素上模擬觸摸

?

等待

當我們使用page.goto等跳轉函數主動跳轉頁面時,本身該函數就是可以異步等待的,可以直接使用await等待跳轉完成。

除此之外,系統也提供了如下等待函數

  • page.waitForNavigation(options)
  • page.waitFor(selectorOrFunctionOrTimeout[, options[, ...args]])
  • page.waitForSelector(selector[, options])
  • page.waitForXPath(xpath[, options])
  • page.waitForFunction(pageFunction[, options[, ...args]])

其中最常用的是page.waitForNavigation,常用於等待跳轉結束,例如點擊搜索按鈕後,等待跳轉至搜索結果頁面。

const?navigationPromise?=?page.waitForNavigation();
await?page.click(‘a.my-link‘);?
await?navigationPromise;?

另外,我們如果需要更細粒度的等待,可以使用其它幾個wait函數,如如果我們要等待某圖片的第一次加載。

?

執行腳本

執行腳本最常用的函數是page.evaluate,它類似於在控制臺中執行指令。

console.log(await page.evaluate(‘1 + 2‘));
var title = await page.evaluate(‘document.title‘)

它也可以用來執行寫好的node函數,實際上該函數是在瀏覽器中執行的,但可以像本地函數一樣編寫,還支持參數傳值。

var?title?=?await?page.evaluate(async?(i)?=>?{
????return?document.title?+?‘?‘?+?i;
},?‘hello‘);

console.log(title);

雖然這node函數不能調試,但仍然是有非常大的好處的,

  1. 不用考慮字符串轉義的問題,書寫起來非常直接
  2. 腳本在IDE中有高亮顯示和智能提示的,寫起來更加方便

另外,還有幾個其它的執行腳本的函數,應用於不同的場合,也是非常有用的。

  1. page.evaluateHandle(pageFunction, ...args)
  2. page.evaluateOnNewDocument(pageFunction, ...args)
  3. page.$$eval(selector, pageFunction[, ...args])
  4. page.$eval(selector, pageFunction[, ...args])

例如:

const?searchValue?=?await?page.$eval(‘#search‘,?el?=>?el.value);
const?preloadHref?=?await?page.$eval(‘link[rel=preload]‘,?el?=>?el.href);
const?html?=?await?page.$eval(‘.main-container‘,?e?=>?e.outerHTML);

?

信息查看

puppeteer提供了一些查看頁面信息的函數,

  1. page.url()
  2. page.content()
  3. page.frames()
  4. page.mainFrame()
  5. page.metrics()
  6. page.target()
  7. page.title()
  8. page.viewport()

?

請求中斷

page.setRequestInterception提供了中斷請求的機制,例如,我們可以通過它實現一個無圖模式。

await?page.setRequestInterception(true);
page.on(‘request‘,?interceptedRequest?=>?{
????if?(interceptedRequest.url().endsWith(‘.png‘)?||?interceptedRequest.url().endsWith(‘.jpg‘))
????????interceptedRequest.abort();
????else
????????interceptedRequest.continue();
});
await?page.goto(‘https://example.com‘);

這裏有一個interceptedRequest對象,它提供了三種響應模式:abort、continue和respond。

?

內容註入

內容保存主要包括註入javascript和style,都是非常有用的函數。

  1. page.addScriptTag(options)
  2. page.addStyleTag(options)

?

事件

puppteer提供了一系列事件的通知:

close

frameattached

pageerror

console

framedetached

request

dialog

framenavigated

requestfailed

domcontentloaded

load

requestfinished

error

metrics

response

簡單的示例如下:

page.on(‘load‘,
????async?()?=>?{
????????console.log(‘page?loading?done,?start?fetch...‘);
????});

?

內容保存

內容保存主要包括保存為pdf和截圖

  1. page.pdf(options)
  2. page.screenshot([options])

?

不常用

另外,還有一些用的較少的函數,但一旦用上也是能解決比較問題的。

  1. page.authenticate(credentials)
  2. page.bringToFront()
  3. page.browser()
  4. page.close(options)
  5. page.coverage
  6. page.exposeFunction(name, puppeteerFunction)
  7. page.queryObjects(prototypeHandle)
  8. page.setBypassCSP(enabled)
  9. page.setCacheEnabled(enabled)
  10. page.setContent(html)
  11. page.setDefaultNavigationTimeout(timeout)
  12. page.setJavaScriptEnabled(enabled)
  13. page.setOfflineMode(enabled)
  14. page.tracing

除了page對象外,還有其他的幾個對象,如果有空再詳細的介紹一下。

使用Puppeteer進行數據抓取(二)——Page對象