index.html:css
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> </head> <script> function appendEle(info) { var node = document.createElement("LI"); var textnode = document.createTextNode(info); node.appendChild(textnode); document.getElementById("add").appendChild(node); } function clickbutton() { appendEle("你點擊了外部按鈕"); } </script> <body> <div><button id='outerbutton' onclick='clickbutton()' >外部按鈕</button></div> <br> <div class="baiyueheiyu"><span>下面的內容是iframe中的</span></div> <iframe src="sample1.html" id='frame1' name='innerFrame' width="300" height="200"></iframe> <div id="add"></div> </body> </html>
sample1.html:html
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> <style type="text/css"> .wolf{ color: red; } </style> </head> <body> <div class="raise"><span>喜羊羊</span></div> <div class="raise"><span>美羊羊</span></div> <div class="raise"><span>暖羊羊</span></div> <div class="wolf"><span>灰太狼</span></div> <div class="wolf"><span>紅太狼</span></div> <div class="wolf"><span>小灰灰</span></div> </body> </html>
若是咱們要選擇下圖方框中全部的羊,使用css選擇,怎麼寫表達式?node
固然,要先查看到它們的html元素特徵web
你們可能會照舊寫出以下代碼: chrome
from selenium import webdriver wd = webdriver.Chrome(r'E:\webdrivers\chromedriver.exe') wd.get('http://127.0.0.1:8020/day01/index.html') # 根據class name選擇元素,返回的是一個列表 elements = wd.find_elements_by_class_name('raise') for element in elements: print(element.text)
運行一下,你就會發現,運行結果打印內容爲空白,說明沒有選擇到class屬性值爲raise的元素。瀏覽器
爲何呢?app
由於仔細看,你能夠發現,這些元素是在一個叫iframe的元素中的。測試
這個iframe元素很是的特殊,在html語法中,frame元素或者iframe元素的內部,會包含一個被嵌入的另外一份html文檔。 網站
在咱們使用selenium打開一個網頁時,咱們的操做範圍缺省是當前的html,並不包含被嵌入的html文檔裏面的內容。spa
若是咱們要操做被嵌入的html文檔中的元素,就必須切換操做範圍到被嵌入的文檔中。
怎麼切換呢?
使用WebDriver對象的switch_to屬性,像這樣:
wd.switch_to.frame(frame_reference)
其中,frame_reference能夠是frame元素的屬性name或者ID。
好比這裏,就能夠填寫iframe元素的id‘frame1’或者name屬性值‘innerFrame’。
像這樣
wd.switch_to.frame('frame1')
或者
wd.switch_to.frame('innerFrame')
也能夠填寫frame 所對應的 WebElement 對象。
咱們能夠根據frame的元素位置或者屬性特性,使用find系列的方法,選擇到該元素,獲得對應的WebElement對象。
好比,這裏就能夠寫:
wd.switch_to.frame(wd.find_element_by_tag_name("iframe"))
而後,就能夠進行後續操做frame裏面的元素了。
上面的例子的正確代碼以下:
from selenium import webdriver wd = webdriver.Chrome(r'E:\webdrivers\chromedriver.exe') wd.get('http://127.0.0.1:8020/day01/index.html') # 先根據name屬性值 'innerFrame',切換到iframe中 wd.switch_to.frame('innerFrame') # 根據 class name 選擇元素,返回的是 一個列表 elements = wd.find_elements_by_class_name('raise') for element in elements: print(element.text)
若是咱們已經切換到某個iframe裏面進行操做了,那麼後續選擇和操做界面元素就都是在這個frame裏面進行的。
這時候,若是咱們又須要操做主html(咱們把最外部的html稱之爲主html)裏面的元素了呢?
怎麼切換回原來的主html呢?
很簡單,寫以下代碼便可:
wd.switch_to.default_content()
例如,在上面代碼操做完frame裏面的元素後,須要點擊主html裏面的按鈕,就能夠這樣寫:
from selenium import webdriver wd = webdriver.Chrome(r'E:\webdrivers\chromedriver.exe') wd.get('http://127.0.0.1:8020/day01/index.html') # 先根據name屬性值 'innerFrame',切換到iframe中 wd.switch_to.frame('innerFrame') # 根據 class name 選擇元素,返回的是 一個列表 elements = wd.find_elements_by_class_name('raise') for element in elements: print(element.text) # 切換回 最外部的 HTML 中 wd.switch_to.default_content() # 而後再 選擇操做 外部的 HTML 中 的元素 wd.find_element_by_id('outerbutton').click()
在網頁上操做的時候,咱們常常遇到,點擊一個連接或者按鈕,就會打開一個新窗口。
html代碼:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>主html</title> </head> <script> function appendEle(info) { var node = document.createElement("LI"); var textnode = document.createTextNode(info); node.appendChild(textnode); document.getElementById("add").appendChild(node); } function clickbutton() { appendEle("你點擊了外部按鈕"); } </script> <body> <a href="http://www.bing.com" target="_blank">訪問bing網站</a> <div><button id='outerbutton' onclick='clickbutton()' >功能按鈕</button></div> <br> <div id="add"></div> </body> </html>
在打開的網頁中,點擊 連接 「訪問bing網站」 , 就會彈出一個新窗口,訪問bing網址。
若是咱們用Selenium寫自動化程序在新窗口裏面打開一個新網址,而且去自動化操做新窗口裏面的元素,會有什麼問題呢?
問題就在於,即便新窗口打開了,這時候,咱們的 WebDriver對象對應的仍是老窗口,自動化操做也仍是在老窗口進行,咱們能夠運行以下代碼驗證一下:
from selenium import webdriver wd = webdriver.Chrome(r'E:\webdrivers\chromedriver.exe') wd.implicitly_wait(10) wd.get('http://127.0.0.1:8020/day01/index.html') # 點擊打開新窗口的連接 link = wd.find_element_by_tag_name("a") link.click() # wd.title屬性是當前窗口的標題欄 文本 print(wd.title)
運行完程序後,最後一行打印當前窗口的標題欄文本,輸出內容是:
主html
說明,咱們的 WebDriver對象指向的仍是老窗口,不然的話,運行結果就應該新窗口的標題欄「微軟Bing搜索」。
若是咱們要到新的窗口裏面操做,該怎麼作呢?
可使用Webdriver對象的switch_to屬性的window方法,以下所示:
wd.switch_to.window(handle)
其中,參數handle須要傳入什麼呢?
WebDriver對象有window_handles屬性,這是一個列表對象,裏面包括了當前瀏覽器裏面全部的窗口句柄。
所謂句柄,你們能夠想象成對應網頁窗口的一個ID,那麼咱們就能夠經過 相似下面的代碼:
for handle in wd.window_handles: # 先切換到該窗口 wd.switch_to.window(handle) # 獲得該窗口的標題欄字符串,判斷是否是咱們要操做的那個窗口 if 'Bing' in wd.title: # 若是是,那麼這時候WebDriver對象就是對應的該該窗口,正好,跳出循環, break
上面代碼的用意就是:
咱們依次獲取wd.window_handles裏面的全部 句柄 對象,而且調用wd.switch_to.window(handle)方法,切入到每一個窗口,而後檢查裏面該窗口對象的屬性(能夠是標題欄,地址欄),判斷是否是咱們要操做的那個窗口,若是是,就跳出循環。
完整代碼:
from selenium import webdriver wd = webdriver.Chrome(r'E:\webdrivers\chromedriver.exe') wd.implicitly_wait(10) wd.get('http://127.0.0.1:8020/day01/index.html') # 點擊打開新窗口的連接 link = wd.find_element_by_tag_name("a") link.click() for handle in wd.window_handles: # 先切換到該窗口 wd.switch_to.window(handle) # 獲得該窗口的標題欄字符串,判斷是否是咱們要操做的那個窗口 if 'Bing' in wd.title: # 若是是,那麼這時候WebDriver對象就是對應的該該窗口,正好,跳出循環, break # wd.title屬性是當前窗口的標題欄 文本 print(wd.title)
一樣的,若是咱們在新窗口 操做結束後,還要回到原來的窗口,該怎麼辦?
咱們能夠仍然使用上面的方法,依次切入窗口,而後根據標題欄之類的屬性值判斷。
還有更省事的方法。
由於咱們一開始就在原來的窗口裏面,咱們知道進入新窗口操做完後,還要回來,能夠事先保存該老窗口的句柄,使用以下方法:
# mainWindow變量保存當前窗口的句柄 mainWindow = wd.current_window_handle
切換到新窗口操做完後,就能夠直接像下面這樣,將driver對應的對象返回到原來的窗口。
#經過前面保存的老窗口的句柄,本身切換到老窗口 wd.switch_to.window(mainWindow)
完整代碼:
from selenium import webdriver wd = webdriver.Chrome(r'E:\webdrivers\chromedriver.exe') wd.implicitly_wait(10) wd.get('http://127.0.0.1:8020/day01/index.html') # mainWindow變量保存當前窗口的句柄 mainWindow = wd.current_window_handle # wd.title屬性是當前窗口的標題欄 文本 print(wd.title) # 點擊打開新窗口的連接 link = wd.find_element_by_tag_name("a") link.click() for handle in wd.window_handles: # 先切換到該窗口 wd.switch_to.window(handle) # 獲得該窗口的標題欄字符串,判斷是否是咱們要操做的那個窗口 if 'Bing' in wd.title: # 若是是,那麼這時候WebDriver對象就是對應的該該窗口,正好,跳出循環, break # wd.title屬性是當前窗口的標題欄 文本 print(wd.title) #經過前面保存的老窗口的句柄,本身切換到老窗口 wd.switch_to.window(mainWindow) # wd.title屬性是當前窗口的標題欄 文本 print(wd.title)
結果:
主html 微軟 Bing 搜索 - 國內版 主html
經過測試的結果,咱們能夠看到窗口切換了兩次。