瀏覽器支持跨域,說實話在puppeteer裏面其實意義不太大,自己就在node環境中。可是在咱們測試項目和一些特殊場景下的操做中,的確可能就須要這樣的能力,所以此文做爲讓puppeteer支持跨域的一種記錄。
這裏先解釋下跨域,有基礎的同窗能夠直接看下面的幾種跨域方式,跳過這裏。html
跨域的判斷:node
page.setBypassCSP(enabled)
enabled
[boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Boolean_type)) sets bypassing of page's Content-Security-Policy.- returns: [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise))
Toggles bypassing page's Content-Security-Policy.git
NOTE CSP bypassing happens at the moment of CSP initialization rather then evaluation. Usually this means that
page.setBypassCSP
should be called before navigating to the domain.github
api很是簡單,就是放入一個布爾值。說了那麼多,其實最主要的是一個點: 導航開始前應該調用完畢它。web
只要確保代碼在此以前執行,就不會有太大問題。ajax
另一個api是: page.setRequestInterception https://github.com/puppeteer/puppeteer/blob/master/docs/api.md#pagesetrequestinterceptionvaluechrome
這個官方給出了例子,也說得很直白:npm
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');api
這裏惟一要注意的一個隱藏操做是:啓用了攔截,那麼就會自動開啓無緩存狀態。跨域
let page = await browser.newPage();
await page.goto(`https://www.baidu.com`);
//第一種是直接選擇元素,當元素在頁面裏執行了某個功能,返回回來一個結果
let result = await page.$eval('#kw', (el)=>{
//...作一些事情
return new Promise((resolve,reject)=>{//等待一個Promise完成,當點擊了才能繼續下一步
el.addEventListener('click',()=>{
resolve('我執行完了!')
})
})
});
console.log(result)//從頁面裏面發回的結果
這樣的話,就實現了抓取好了,再次進入頁面裏面作一些其餘操做。類似的功能還有很多,能夠參考官方文檔裏。
const result = await page.evaluate(x => {
return Promise.resolve(8 * x);
}, 7);//後面的這個參數是要node環境傳入的值
console.log(result); // prints "56"
官方還提供了一個方法:page.exposeFunction(name, puppeteerFunction)
https://github.com/puppeteer/puppeteer/blob/master/docs/api.md#pageexposefunctionname-puppeteerfunction
其實就是能夠容許你掛在一個node方法在window下,而後在頁面執行環境中,能夠去調用到這個node方法,比較推薦的仍是這種官方的作法。
官方案例:
const puppeteer = require('puppeteer');
const fs = require('fs');
(async () => {
const browser = await puppeteer.launch();
const page = await browser.newPage();
page.on('console', msg => console.log(msg.text()));
await page.exposeFunction('readfile', async filePath => {
return new Promise((resolve, reject) => {
fs.readFile(filePath, 'utf8', (err, text) => {
if (err)
reject(err);
else
resolve(text);
});
});
});
await page.evaluate(async () => {
// use window.readfile to read contents of a file
const content = await window.readfile('/etc/hosts');
console.log(content);
});
await browser.close();
})();
Puppeteer 系列踩坑日誌—2—去掉自動化提示
開篇講到的chrome參數,裏面有很是詳盡的解釋。這裏咱們使用:--disable-web-securityawait puppeteer.launch({
args: [
'--disable-web-security'
]
})
老樣子,仍是看下peter的列表裏咋介紹的:
--disable-web-security ⊗
Don't enforce the same-origin policy. (Used by people testing their sites.) ↪
關閉網頁內容安全策略
不要強制執行同一來源策略。(供測試網站的用戶使用。)
這個參數的做用就是拿來控制內容安全策略的,加完之後,頁面不一樣域名下就能夠無限跨域了。
chrome-extension://XXXXXXX/A.html
的頁面,均可以實現無限跨域。固然,以上目前一共四種方式,若是還有其餘的,歡迎你們補充!