問:什麼是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')});