问:什么是iframe?chrome
答:iframe 元素会建立包含另一个文档的内联框架(即行内框架),咱们常常会遇到登入页面的时候,这个时候咱们直接定位到iframe里的元素是无效的,至关于咱们要切换到相应的iframe,咱们才能找到对应的元素。框架
1.好比登入安居客登入页面,看到这个页面,咱们若是不考虑iframe的话,直接定位到手机号码元素,会不会成功呢,咱们试一下如下代码,过一段时间直接抛出error,说明是行不通的,那么咱们就要分析一下页面元素。less
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呢,咱们看不出来,怎么办?那么咱们就用代码计算一下。async
const frames = await page.frames(); // 获取当前页面的frame
console.log(frames.length); // 打印
3. 根据上面的代码咱们能够获得长度是2说明不止一个iframe,那么咱们找到咱们须要切换的iframe 呢?咱们再分析一下上面的元素截图,发现咱们须要的iframe 有个url属性,指向惟一的url,因此咱们思考用遍历frames 获取每一个url 再与咱们切换的iframe作对比,不就取到了么,代码演示ui
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');
完整代码 =>url
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')});