【PUPPETEER】初探之原生frame切换(四)

一、知识点

  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')});

 

posted @ 2019-08-09 10:47  WANG-X  阅读(1933)  评论(1编辑  收藏  举报