一、知識點
- page.frames()
- 使用frame.url() 獲取framed的url
- 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')});