这里不讲 Puppeteer 怎么使用,主要讲一些常规操作在这里如何通过另类方法实现。等实现后,你就会感觉,嗯~~ 真香!

场景一

已经找出要的元素,现在有需求再继续寻找他的子元素

  • 第一种、将父元素带入 evaluate 事件中
// 已经找出父元素
const foo = await page.$('.foo');
// 将父元素带入 `evaluate` 事件中,通过原生方法继续后续操作
const bar = await page.evaluate(fooEle => fooEle.querySelector('.bar'), foo);

这里的 evaluate 好处就是 callback 里面可以通过原生js进行操作,callback 后面的 argument 以逗号形式分割,顺序传入 callback 中。

  • 第二种、继续通过原本的操作
// 已经找出父元素
const foo = await page.$('.foo');
// 继续通过原本的操作
const bar = await foo.$('.bar');

这里比较通俗易懂,page 找出的对象后面其实是继续给了 page 的所有方法,但由于 page 大部分方法都是异步 <Promise> 的,所以必须等待完成才可以操作,不能使用链式操作。

这里主要看习惯哪一种操作,第一种的好处习惯原生js,但是大部分操作只能在 callback 中操作,类似 page.$eval 等操作;第二种的好处是直接操作,不含糊,让人觉得更舒服一点,不管以后做输入还是点击,都非常方便。

场景二

每次做点击/输入之前都要进行验证即将操作对象是否存在

// 封装需要等待
// 等待出现
const waitPre = async(st) =>
await page.waitFor(selector =>
!!document.querySelector(selector), {}, st);
// 等待消失
const waitFade = async(st) =>
await page.waitFor(selector =>
!document.querySelector(selector), {}, st); await waitPre('.foo'); // await page.waitFor('.foo');
await page.click('.foo');
// await waitPre('.foo');
// dosomething...

这里不做过多解释,非人操作都很快,不像人一样还看到后再操作。

场景三

当点击造成页面跳转或者重新加载时,需要等待页面加载完成。

const [response] = awiat Promise.all([
page.waitFroNavigation(),
page.click('.btn'), // 点击导致页面跳转(重载)
]); response

response 是加载dom时的响应对象。

场景四

当主动让页面跳转(重载),而且这里也需要监听重载后的某个请求的响应对象。

  • 第一种、等待 reload 完成后再监听
await page.reload(); // 也可以加option,但这里想到要监听某个请求,故为空
await const response = await page.waitForResponse(response => {}); response

这种监听方式有可能会漏掉某些请求。

  • 第二种、直接通过 on 监听
page.on('response', response => {});
await page.reload();

这里的监听无任何限制,无论页面做什么操作,都不会逃过 on 的法眼。

场景五

我想删除所有文本,这里只能通过 keyboard 来实现。

  • 第一种、计算长度,逐个删除
const cls = '.foo';
await page.waitFor(cls);
await page.focus(cls);
const len = await page.$eval(cls, el => el.textContent.length);
for (let i = 0; i < len; i++) {
await page.keyboard.press('Backspace');
}
await page.type(cls, 'something');

通过循环删除,不推荐

  • 第二种、计算长度,选中,删除
const cls = '.foo';
await page.waitFor(cls);
await page.focus(cls);
const text = await page.$eval(cls, el => el.textContent.length);
await page.keyboard.down('Shift');
for (let i = 0; i < text.length; i++) {
await page.keyboard.press('ArrowLeft');
}
await page.keyboard.up('Shift');
await page.keyboard.press('Backspace');
await page.type(cls, 'something');

循环选中,一次性删除。

  • 第三种、全选,一次性删除
const cls = '.foo';
await page.waitFor(cls);
await page.focus(cls);
const text = await page.$eval(cls, el => el.textContent.length);
await page.keyboard.down('ControlLeft');
await page.keyboard.press('KeyA');
await page.keyboard.up('ControlLeft');
await page.keyboard.press('Backspace');
await page.type(cls, 'something');

Mac os x 上这里未实现,这种方法不可用。目前推荐使用第二种方法,等官方消息。

Mac os x 上 不支持。

Puppeteer-常规操作一的更多相关文章

  1. FTP服务器常规操作

    导读 FTP协议是Internet文件传输的基础,它是由一系列规格说明文档组成,目标是提高文件的共享性,提供非直接使用远程计算机,使存储介质对用户透明和可靠高效地传送数据.下面就由我给大家简单介绍一下 ...

  2. Apache服务器常规操作

    导读 Apache是世界上排名第一的Web服务器,50%以上的Web服务器都在使用Apache,它几乎可以在所有计算机平台上运行.下面就由我给大家说说Apache服务器的一些常规操作. Apache服 ...

  3. mysql服务器的常规操作

    mysql服务器的常规操作 导读 MySQL是一个小型关系数据库管理系统,目前被广泛的应用在Internet上的中小型网站中,体积小.速度快.总体拥有成本低,尤其是开放源码这一特点,使得许多中小型网站 ...

  4. 征服 Redis + Jedis + Spring (一)—— 配置&常规操作(GET SET DEL)

    有日子没写博客了,真的是忙得要疯掉. 完成项目基础架构搭建工作,解决了核心技术问题,接着需要快速的调研下基于Spring框架下的Redis操作. 相关链接: 征服 Redis 征服 Redis + J ...

  5. Mongodb常规操作【一】

    Mongodb是一种比较常见的NOSQL数据库,数据库排名第四,今天介绍一下Net Core 下,常规操作. 首先下C# 版的驱动程序 "MongoDB.Driver",相关依赖包 ...

  6. C#通过Ado.net对连接数据库并进行添加删除等常规操作的代码

    如下资料是关于C#通过Ado.net对连接数据库并进行添加删除等常规操作的内容. static string sqlcon = "server=.;database=;Integrated ...

  7. react-native 常规操作

    1.  关闭xcode打开模拟器的快捷键 , 等常规操作 https://www.jianshu.com/p/f6723f3406b7

  8. Linux 下的 netfilter 认识与常规操作

    Linux 下的 netfilter 认识与常规操作 前言 博客写到今天,1年7个月.可是包含所有写作经历,这个时间线可以达到三年. 上次更新了一篇 "镇站之宝" ,也是本站阅读量 ...

  9. 数据库mysql的常规操作

    1. 什么是数据库? 数据库(Database)是按照数据结构来组织.存储和管理数据的建立在计算机存储设备上的仓库. 简单来说是本身可视为电子化的文件柜——存储电子文件的处所,用户可以对文件中的数据进 ...

  10. Learn Docker(一)—软件安装与常规操作

    一.安装Docker Windows平台 在Windows10 X64专业版上可以直接下载Docker原生应用进行安装,在控制面板的程序与功能里启用Hyper-v,之后就可以运行docker程序啦. ...

随机推荐

  1. 关于Android ListView组件中android:drawSelectorOnTop含义(转载)

    转自:http://yangguangfu.iteye.com/blog/902559 When set to true, the selector will be drawn over the se ...

  2. JDK由浅到深的理解

    一.JDK的安装 二.JDK安装后目录下的文件夹的用处 bin:编译器(javac.exe); db:jdk从1.6之后内置Derby数据库,它是一个纯用Java实现的内存数据库,Apache的开源项 ...

  3. 鸟哥私房菜基础篇:Linux 的档案权限与目录配置习题

    猫宁!!! 参考链接:http://linux.vbird.org/linux_basic/0210filepermission.php 鸟哥是为中国信息技术发展做出巨大贡献的人. 1-早期的 Uni ...

  4. Luogu2261[CQOI2007]余数求和 【数论】By cellur925

    题目传送门 省选题竟然送了这么多分,60分直接暴力算就行.(算了,07年的省选) 数学题嘛,通常我们需要把式子展开,然后寻找一些性质化简=w=. 展开式以及寻找规律的过程lyd老师讲的很清楚T_T,放 ...

  5. profile和bashrc

    转自某不知名网友 /etc/profile,/etc/bashrc 是系统全局环境变量设定~/.profile,~/.bashrc用户家目录下的私有环境变量设定当登入系统时候获得一个shell进程时, ...

  6. MySql | 常用操作总结

    创建数据库: CREATE DATABASE 数据库名; 删除数据库名: drop database <数据库名>; 选择数据库: use 数据库名; 创建数据表: CREATE TABL ...

  7. JSP | 基础 | JSP状态管理 | Cookie

    Cookie : 是web服务器保存在客户端的一系列文本信息. Cookie的作用: 1.对特定的对象的追踪 2. 3. JSP中创建Cookie以及使用 创建Cookie对象 写入Cookie对象 ...

  8. redis启停

    1 查看服务器上启动的redis服务 开了两个redis单机服务,监听在两个端口. 开了一个集群,监听在6个端口. [root@localhost bin]# ps aux | grep redis ...

  9. 简单实现人工智能:百度aip+tuling123

    目录结构: app.py # -*- coding: utf-8 -*- # __author: ward # data: 2018/12/21 # @File: app from flask imp ...

  10. 492 Construct the Rectangle 构建矩形

    详见:https://leetcode.com/problems/construct-the-rectangle/description/ C++: class Solution { public: ...