浏览器支持跨域,说实话在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
的页面,均可以实现无限跨域。固然,以上目前一共四种方式,若是还有其余的,欢迎你们补充!