在做web自動化的過程中會遇到一些彈出的登錄頁面,定位后,執行程序發現還是出現報錯,其實定位可能沒有問題,而是表單再作怪,也就是iframe
iframe
iframe是HTML標簽,作用是文檔中的文檔,或者浮動的框架(FRAME)。iframe元素會創建包含另外一個文檔的內聯框架,也就html中在嵌套一個網頁
iframe長什么樣子
我們通常登錄的163郵箱其實就是iframe。可以通過F12查看
如何定位iframe
我們知道什么是iframe了,那么如何定位?我們可以使用selenium中自帶的一個方法 switch_to_frame ,這里的定位iframe可以是id屬性也可以是name屬性
源碼
def switch_to_frame(self, frame_reference): """ Deprecated use driver.switch_to.frame """ warnings.warn("use driver.switch_to.frame instead", DeprecationWarning, stacklevel=2) self._switch_to.frame(frame_reference)
小試牛刀
方法一:
這里安靜通過switch_to_frane方法進行定位,這里的iframe的ID為動態id,每次啟動都不通,使用正則表達式抓取
from selenium import webdriver import time import re driver = webdriver.Chrome() driver.get('https://mail.163.com/') # 獲取頁面HTML html = driver.page_source # 找到iframe的id,這里iframe是動態的 r = re.findall(r'<iframe name="" frameborder="0" id="(.+?)" scrolling',html)[0] # 跳轉到iframe上 driver.switch_to_frame(r) time.sleep(2) # 定位輸入框 driver.find_element_by_name('email').send_keys('821006052')
上面我們在pychram代碼中會發現,switch_to_frame()中有橫線,這里官方是不建議使用的,我們可以使用switch_to.frame()
方法二:
前面介紹了顯示等待以及等待元素的幾種方法,這里我們也可以通過顯示等待,循環查看是否存在iframe,然后進行跳轉進去
from selenium import webdriver from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.support.ui import WebDriverWait import time import re driver = webdriver.Chrome() driver.get('https://mail.163.com/') # 獲取頁面HTML html = driver.page_source # 找到iframe的id,這里iframe是動態的 r = re.findall(r'<iframe name="" frameborder="0" id="(.+?)" scrolling',html)[0] # 通過顯示等待的方法進行檢測iframe是否出現,並跳轉 WebDriverWait(driver,10,0.5).until(EC.frame_to_be_available_and_switch_to_it(r)) time.sleep(2) driver.find_element_by_name('email').send_keys('821006052')
方法三:
從上面觀察發現iframe后面的一些數字為動態的,可以通過在CSS定位方法中,可以通過“^=”匹配id屬性為以“x-URS-iframe“開頭的元素進行定位。
from selenium import webdriver import time import re driver = webdriver.Chrome() driver.get('https://mail.163.com/') # 獲取頁面HTML html = driver.page_source time.sleep(2) # 通過Css方法定位 r = driver.find_element_by_css_selector('iframe[id^="x-URS-iframe"]') driver.switch_to_frame(r) driver.find_element_by_name('email').send_keys('821006052')
跳轉回原頁面
執行完iframe上的操作后,需要跳轉會原頁面上,這里需要使用方法: switch_to.default_content() 和 switch_to.parent_frame()
源碼:
def default_content(self): """ Switch focus to the default frame. :Usage: driver.switch_to.default_content() """ self._driver.execute(Command.SWITCH_TO_FRAME, {'id': None})
源碼:
def parent_frame(self): """ Switches focus to the parent context. If the current context is the top level browsing context, the context remains unchanged. :Usage: driver.switch_to.parent_frame() """ self._driver.execute(Command.SWITCH_TO_PARENT_FRAME)
快速查看定位元素是否處於iframe上
這里打開F12,通過ctrl+F,找到需要定位的元素,觀察是否有iframe上。
安靜簡單的介紹了跳轉iframe的過程,如果那里有不懂的或者寫錯的地方,都可以下方留言,感謝支持~