一、知识点

  1. page.frames()
  2. 使用frame.url() 获取framed的url
  3. x.getAttribute('x') 获取元素内值

二、实例

  问:什么是iframe?

  答:iframe 元素会创建包含另外一个文档的内联框架(即行内框架),我们经常会遇到登入页面的时候,这个时候我们直接定位到iframe里的元素是无效的,相当于我们要切换到相应的iframe,我们才能找到对应的元素。

  1.比如登入安居客登入页面,看到这个页面,我们如果不考虑iframe的话,直接定位到手机号码元素,会不会成功呢,我们试一下以下代码,过一段时间直接抛出error,说明是行不通的,那么我们就要分析一下页面元素。

const puppeteer = require('puppeteer');
(async () => {
const brower = await puppeteer.launch({
executablePath:'D:\\wangxiao\\chrome-win\\chrome-win\\chrome.exe',
headless:false
});
const page = await brower.newPage();
await page.goto('https://suzhou.anjuke.com/');
await page.click('#login_l a:nth-child(1)'); // 点击登入
await page.waitFor('#phoneIpt'); // 等待元素
const input = await page.$('#phoneIpt'); // 获取登入框元素
await input.type('122222');// 输入
await page.close();
})().catch(error =>{console.log('error')});

  2. 我们分析页面元素,发现登入页面有iframe,但是再网上翻,但是到底有几个iframe呢,我们看不出来,怎么办?那么我们就用代码计算一下。

const frames = await page.frames();  // 获取当前页面的frame
console.log(frames.length); // 打印

  3. 根据上面的代码我们可以得到长度是2说明不止一个iframe,那么我们找到我们需要切换的iframe 呢?我们再分析一下上面的元素截图,发现我们需要的iframe 有个url属性,指向唯一的url,所以我们思考用遍历frames 获取每个url 再与我们切换的iframe做对比,不就取到了么,代码演示

    const url = await page.$eval('#iframeLoginIfm',el => el.getAttribute('src'));   //  通过iframe id 元素,获取src的值
const frames = await page.frames(); // 获取当前页面的所有的 frame
  // 遍历frame,当frame的url 包含再目标url中,则是当前我们需要的frame

for (let i of frames) {
if (url.includes(i.url())) {
var frame = i ;
}
}
await frame.waitFor('#phoneIpt');
await frame.type('#phoneIpt','122222');

完整代码 =>

const puppeteer = require('puppeteer');
(async () => {
const brower = await puppeteer.launch({
executablePath:'D:\\wangxiao\\chrome-win\\chrome-win\\chrome.exe',
headless:false
});
const page = await brower.newPage();
await page.goto('https://suzhou.anjuke.com/');
await page.click('#login_l a:nth-child(1)');
const url = await page.$eval('#iframeLoginIfm',el => el.getAttribute('src'));
const frames = await page.frames();
for (let i of frames) {
if (url.includes(i.url())) {
var frame = i ;
}
}
await frame.waitFor('#phoneIpt');
await frame.type('#phoneIpt','122222');
//await brower.close();
})().catch(error =>{console.log('error')});

【PUPPETEER】初探之原生frame切换(四)的更多相关文章

  1. 初探云原生应用管理(二): 为什么你必须尽快转向 Helm v3

    系列介绍:这个系列是介绍如何用云原生技术来构建.测试.部署.和管理应用的内容专辑.做这个系列的初衷是为了推广云原生应用管理的最佳实践,以及传播开源标准和知识.在这个系列文章的开篇初探云原生应用管理(一 ...

  2. ionic-native-transitions调用原生页面切换实现ionic路由切换

    废话不多说:ionic-native-transitions调用原生页面切换实现ionic路由切换,从而大大提升ionic应用的性能. ionic-native-transitions是一个ionic ...

  3. HTML5实战与剖析之原生拖拽(四可拖动dragable属性和其他成员)

    可拖动dragable属性 之前我们已经为大家介绍过几篇有关HTML5中原生拖拽的相关知识了.今天为大家介绍HTML5拖拽中的其他一些小东东,闲话不多说赶快一起看看吧. 在默认情况下,链接.文本和图像 ...

  4. 初探云原生应用管理(一): Helm 与 App Hub

      ​ 系列介绍:初探云原生应用管理系列是介绍如何用云原生技术来构建.测试.部署.和管理应用的内容专辑.做这个系列的初衷是为了推广云原生应用管理的最佳实践,以及传播开源标准和知识.通过这个系列,希望帮 ...

  5. 原生tab切换

    <html><head><meta http-equiv="Content-Type" content="text/html; charse ...

  6. selenium+java多层级frame切换的问题

    关于selenium多层iframe切换,及iframe没有id和name属性的情况下进行切换的问题.(如下图:) 问题: 1. 在切入到frame:left中后,直接切换其他同级和上级frame报错 ...

  7. Selenium(六):frame切换、窗口切换

    1. 切换到frame index.html: <!DOCTYPE html> <html> <head> <meta charset="UTF-8 ...

  8. 初探云原生应用管理之:聊聊 Tekton 项目

    [编者的话]“人间四月芳菲尽,山寺桃花始盛开.” 越来越多专门给 Kubernetes 做应用发布的工具开始缤纷呈现,帮助大家管理和发布不断增多的 Kubernetes 应用.在做技术选型的时候,我们 ...

  9. eclipse中英文切换--四种方式

    若转载,请注明出处 http://www.cnblogs.com/last_hunter/p/5627009.html 谢谢! ------------------------------------ ...

随机推荐

  1. 标签平滑(Label Smoothing)详解

    什么是label smoothing? 标签平滑(Label smoothing),像L1.L2和dropout一样,是机器学习领域的一种正则化方法,通常用于分类问题,目的是防止模型在训练时过于自信地 ...

  2. toolbox docker国内镜像(阿里云加速器)

    docker-machine create --engine-registry-mirror=加速地址 -d virtualbox default# 若虚拟机已经创建好docker-machine s ...

  3. Navicat连接Mysql8.0.17出现1251错误 / 或者Navicat Premium出现2059错误

    Navicat连接Mysql8.0.17出现1251错误 重装了电脑之后,好多软件出了问题,经过一系列的插件安装,mysql终于安装好了 但是Navicat又抽筋了~~~额(⊙o⊙)... 在网上查的 ...

  4. [String] intern()方法

    intern()方法设计的初衷,就是重用String对象,以节省内存消耗. JDK1.6以及以前版本中,常量池是放在 Perm 区(属于方法区)中的,熟悉JVM的话应该知道这是和堆区完全分开的. 使用 ...

  5. C# 9.0 新特性预览 - init-only 属性

    C# 9.0 新特性预览 - init-only 属性 前言 随着 .NET 5 发布日期的日益临近,其对应的 C# 新版本已确定为 C# 9.0,其中新增加的特性(或语法糖)也已基本锁定,本系列文章 ...

  6. selenium中的三种等待方式

    1.强制等待,采用的time.sleep,然后后面加上要等待的时间: 2.隐性等待implicitly_wait,隐性等待设定后,会对之后的所有代码生效,会在设定的时间之内,不停的去查找元素,如果找到 ...

  7. golang1.16内嵌静态资源指南

    今天是万圣节,也是golang1.16新特性冻结的日子.不得不说自从go2路线发布之后golang新特性的迭代速度也飞速提升,1.16中有相当多的重要更新,包括io标准库的重构,语言内置的静态资源嵌入 ...

  8. STM32入门系列-STM32外设地址映射

    片上外设区分为四条总线,根据外设速度的不同,不同总线挂载着不同的外设,APB1挂载低速外设,APB2和AHB挂载高速外设.相应总线的最低地址我们称为该总线的基地址,总线基地址也是挂载在该总线上的首个外 ...

  9. centos8 curl: (35) error:141A318A:SSL routines:tls_process_ske_dhe:dh key too small

    centos8操作系统,curl -k https:/www.xxx.com 报错  curl: (35) error:141A318A:SSL routines:tls_process_ske_dh ...

  10. 记一次因python相互导入包的报错

    先丢报错信息:AttributeError:module 'utils.configHttp' has no attribute 'ConfigHttp' 开始以为是导入包的常规问题,上网搜了一下解决 ...