Puppeteer笔记

1,142 阅读2分钟

Puppeteer笔记

声明

我只是一个菜B,之所以写这些东西,一来为了加深记忆,二来发个文章以后看到也是一种回忆,三来锻炼写文的能力,所以文章写得很烂,不喜勿喷,每一个点进来的都是一种缘分,谢谢了。

介绍

Puppeteer是一个Node库,提供一套可以操作Chrome的API。其取名挺有意思,翻译为“操纵木偶的人;傀儡师 ”,代表着我们可以通过操纵她来完成很多功能,例如:
爬虫,爬取网页上的各种信息; 模拟键盘表单等输入,实现自动化测试等...

开始

因为,因为Puppeteer有很多的异步操作,所以推荐使用的是async/await的写法;这样可读性会更好。所以,Node的版本最少为V7.6.6。

下载

通过npm来下载puppeteer:npm install --save puppeteer

Hello World

下载完成Puppeteer后,可以通过引入来模拟打开一个谷歌浏览器。

const puppeteer = require('puppeteer');

async function run() {
  const brower = await puppeteer.launch({
    headless: false,    
    defaultViewport: {
      width: 1366,
      height: 728
    }
  });
  
  const page = await brower.newPage();
  await page.goto('https://www.baidu.com');
  
  const ipt = await page.$('#kw');
  await ipt.type('Hello World!');
}

run();

以上代码执行后,将会打开一个谷歌浏览器,并且在输入框中输入:Hello World!
这就是Puppeteer的第一个程序,上面代码用到的几个API意义(因为是async/await,所以就直接说意思了,不说返回的是Promise):

API 意义
lauch 返回一个brower示例
newPage 创建一个 Page 实例
goto 跳转到一个页面
type 给DOM元素设置值
$ 选项元素,同querySelector

这就是以上用到的API的一些见解。

获取DOM元素的属性

获取一个元素的属性可以通过:$eval来获取。

代码省略...
const page = await brower.newPage();
await page.goto('https://www.baidu.com');

const iptValue = await page.$eval('#kw', el => el.value);

$eval的第一个参数,是一个选择器,第二个参数是一个函数,代表选中的元素,最终的返回值通过await处理后的,就是第二个参数的返回值。

常用的简单API

对象 API 作用 示例
element type 给DOM元素设置值 el.type('Hello World!');
element click 模拟DOM元素的点击事件 el.click();
element uploadFile 模拟DOM元素的上传事件 el.uploadFile('...');
page $ 选取一个元素 page.$('selector');
page ? 选取一组元素 page.?('selector');
page $eval 获取一个元素的属性 page.$('selector', fn => {...});
page ?eval 获取一组元素的属性 page.?eval('selector', fn => {...});
page goto 跳转到一个页面 page.goto('...');

模拟登录掘金点赞一篇文章

通过上面的笔记,我们就可以写一个小Demo——登录掘金,点赞一篇文章!
思路:

  1. 通过goto这个API跳转到掘金首页;
  2. 使用click模拟按登录这个按钮,此时会有一个登录框的弹层;
  3. 使用type这个方法输入用户名和密码,模拟点击登录;
  4. 登录成功后,找到第一篇文章的点赞按钮,模拟点击;
  5. 点赞成功,功能完成!
const puppeteer = require('puppeteer');

async function run() {
  const brower = await puppeteer.launch({
    headless: false,
    defaultViewport: {
      width: 1366,
      height: 768
    }
  });
  
  const page = await brower.newPage();
  await page.goto('https://juejin.im/timeline');

  const loginBtn = await page.$('#juejin > div.view-container > div > header > div > nav > ul > li.nav-item.auth > span.login');
  await loginBtn.click();

  await page.waitForSelector('#juejin > div.global-component-box > div.auth-modal-box > form > div.panel > div.input-group > div:nth-child(1) > input');
  const userInput = await page.$('#juejin > div.global-component-box > div.auth-modal-box > form > div.panel > div.input-group > div:nth-child(1) > input');
  await userInput.type('username');
  
  const pwdInput = await page.$('#juejin > div.global-component-box > div.auth-modal-box > form > div.panel > div.input-group > div:nth-child(2) > input');
  await pwdInput.type('password');

  const loginBtnConfirm = await page.$('#juejin > div.global-component-box > div.auth-modal-box > form > div.panel > button');
  await loginBtnConfirm.click();

  await page.waitForSelector('#juejin > div.view-container.container > main > div > div > div > div > div > ul > li:nth-child(1) > div > div > a > div > div > div.info-row.action-row > ul > li.item.like.clickable > a');
  const goodBtn = await page.$('#juejin > div.view-container.container > main > div > div > div > div > div > ul > li:nth-child(1) > div > div > a > div > div > div.info-row.action-row > ul > li.item.like.clickable > a');
  await goodBtn.click();
}

run();

看看执行效果图

图片失效
图片失效
图片失效

这里有些要注意的

  • 弹出登录框的时候,需要使用waitForSelector这个方法来等待元素加成出来,再用$去选择元素,否则可能会出错
  • 登录后,会刷新页面,所以此时也需要用waitForSelector来等待元素加载完成
  • 这里最新的Chromium浏览器,不知道为啥,我掘金登录只能用邮箱,所以我就绑定了一个。

以上用到的方法主要就几个:
$: 选中元素
click:模拟点击
type: 模拟输入
waitForSelector: 等待元素加载完成

对于这个简单的Demo,仅仅只是Puppeteer的小小开始,我知道笔记记录的又很多不足,但我也会努力学习,慢慢掀开她美丽的面纱

Puppeteer基础开始

概念