Puppeteer 谷歌开发是一个 Node 库,它提供了一个高级 API 来经过 DevTools 协议控制 Chromium 或 Chrome。Puppeteer 默认以 headless 模式运行,可是能够经过修改配置文件运行“有头”模式。javascript
能作啥?css
Puppeteer API 是分层次的,反映了浏览器结构html
这张图须要了解一下,便是puppeteer的结构,也是代码的顺序结构;java
// 浏览器实例
const puppeteer = require('puppeteer');
// 启动 返回 browser
const browser = await puppeteer.launch();
// 返回 page
const page = await browser.newPage();
// 跳转
await page.goto('https://www.baidu.com/');
// 返回page的frame
const frame = await page.mainFrame();
// 当前页面的url https://www.baidu.com/
console.log(frame.url());
// 关闭
await browser.close();
复制代码
// 安装puppeteer,若是报错改用 cnpm 安装
cnpm install puppeteer --save
复制代码
Puppeteer返回的大部分是Promise支持一下async/await会很方便; 每一个功能方法都有不少参数配置,先列举部分git
上方代码内容
github
await page.goto('https://google.com/', {
// 配置项 等待网络状态为空闲的时候才继续执行
waitUntil: 'networkidle'
});
复制代码
await page.screenshot({ path: "download/example.png" });
await page.pdf({
path: "download/example_pdf.pdf',
format: "A4"
});
复制代码
waitFor: 参数能够是<string|number|function> 选择器, 方法 或者 超时时间chrome
// 等待1s
await page.waitFor(1000);
// 等待元素加载完成
await page.waitForSelector("#id");
复制代码
// 返回单个,若是多个返回第一个,没有返回null
const ElementHandle = await page.$("#js_login_select")
// 返回多个,若是没有返回[]
await page.$$(".js_login_select")
复制代码
此方法在页面内执行 document.querySelector,而后把匹配到的元素做为第一个参数传给 pageFunctionnpm
// 获取html
const html = await page.$eval("body", e => e.outerHTML);
console.log(html);
// 获取id
const id = await page.$eval('#div',div => div.id );
//清空输入框的值,获取焦点
await page.$eval('#input',input => {
input.focus();
input.value = '';
})
复制代码
页面实例上下文中执行的方法json
const dimensions = await page.evaluate(param => {
alert("个人方法dimensions和" + param);
return {
width: document.documentElement.clientWidth,
height: document.documentElement.clientHeight,
deviceScaleFactor: window.devicePixelRatio
};
}, "参数");
复制代码
page.evaluate 意为在浏览器环境执行脚本,可传入第二个参数做为句柄,而 page.$eval 则针对选中的一个 DOM 元素执行操做。api
注意:选择器过滤后获得的dom,都是经过执行querySelector或者querySelectorALl获得的,因此页面脚本能执行的方法属性,均可以在这里使用
Puppetter固然能够分析网站的性能,不过是建立一个能够在Chrome DevTools中打开的跟踪文件。
// 每一个浏览器一次只能激活一条跟踪
await page.tracing.start({
path: "download/trace.json",
screenshots: true
});
// 须要关闭
await page.tracing.stop();
复制代码
成功后会在path的位置生成.json的文件,里面一堆的数字和变量~ 打开chrome浏览器的devtools,拖进performance中就OK了~
Puppeteer还能够监听不少事件,load,error,close等等,固然包括request,response
对页面的图片请求拦截,若是不是图片后缀能够找规则筛选
// 启动 request
await page.setRequestInterception(true);
// 监听request
page.on("request", interceptedRequest => {
if (
interceptedRequest.url().endsWith(".png") || interceptedRequest.url().endsWith(".jpg") ||
interceptedRequest.url().includes(".jpg")
) {
// 中断
interceptedRequest.abort();
} else {
interceptedRequest.continue();
}
});
await page.goto("https://www.58pic.com/");
复制代码
await page.addScriptTag({ path: "public/javascripts/test.js" });
await page.addStyleTag({ path: "public/css/test.css" });
复制代码
这样不一样站点,只须要注入不一样的脚本爬取
关于模拟不一样的手机,须要不一样的参数,Puppeteer准备了不少,能够直接拿来用,在puppeteer/DeviceDescriptors中
const page = await browser.newPage();
// 模拟机型
await page.emulate(iPhone);
复制代码