puppeteer介绍(一)爬虫,性能,注入

Puppeteer 谷歌开发是一个 Node 库,它提供了一个高级 API 来经过 DevTools 协议控制 Chromium 或 Chrome。Puppeteer 默认以 headless 模式运行,可是能够经过修改配置文件运行“有头”模式。javascript

能作啥?css

  • 生成页面 PDF,截图。
  • 抓取单页应用执行并渲染
  • 自动提交表单,进行 UI 测试,键盘输入等。
  • 建立一个时时更新的自动化测试环境。
  • 用来帮助分析性能问题。

介绍

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 使用 DevTools 协议 与浏览器进行通讯。
  • Browser 实例能够拥有浏览器。
  • BrowserContext 浏览器上下文。
  • Page 至少有一个框架:主框架。 可能还有其余框架由 iframe 或 框架标签 建立。
  • frame 至少有一个执行上下文 - 默认的执行上下文 - 框架的 JavaScript 被执行。 一个框架可能有额外的与 扩展 关联的执行上下文。
  • Worker 具备单一执行上下文,而且便于与 WebWorkers 进行交互。

安装

// 安装puppeteer,若是报错改用 cnpm 安装
cnpm install puppeteer --save
复制代码

经常使用函数

Puppeteer返回的大部分是Promise支持一下async/await会很方便; 每一个功能方法都有不少参数配置,先列举部分git

浏览器操做、打开页面

上方代码内容github

跳转地址

await page.goto('https://google.com/', {
    // 配置项 等待网络状态为空闲的时候才继续执行
    waitUntil: 'networkidle'
});
复制代码

生成PDF,截图

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");
复制代码

选择器

  • 返回的类型 ElementHandle 表示一个页内的 DOM 元素;
  • 是继承自 JSHandle。而 JSHandle 表示页面内的 JavaScript 对象
  • 实际上是执行的document.querySelector,document.querySelectorAll
// 返回单个,若是多个返回第一个,没有返回null
const ElementHandle = await page.$("#js_login_select")
// 返回多个,若是没有返回[]
await page.$$(".js_login_select")
复制代码

page.$eval(selector, pageFunction[, ...args])

此方法在页面内执行 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 = '';
})
复制代码

evaluate

页面实例上下文中执行的方法json

const dimensions = await page.evaluate(param => {
    alert("个人方法dimensions和" + param);
    return {
        width: document.documentElement.clientWidth,
        height: document.documentElement.clientHeight,
        deviceScaleFactor: window.devicePixelRatio
    };
}, "参数");
复制代码

eval与evaluate区别

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/");
复制代码

注入

  1. addScriptTag:注入一个指定src(url)或者代码(content)的 script 标签到当前页面。
  2. addStyleTag:添加一个指定link(url)的 < link rel="stylesheet" > 标签。 或者添加一个指定代码(content)的 < style type="text/css" > 标签。
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);
复制代码

相关文章
相关标签/搜索