Selenium(六):frame切換、窗口切換

1. 切換到frame

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

1.1 從主html切換到被嵌入的文檔

若是咱們要操做被嵌入的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)

1.2 從被嵌入的文檔切換到主html

若是咱們已經切換到某個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()

2. 切換窗口

在網頁上操做的時候,咱們常常遇到,點擊一個連接或者按鈕,就會打開一個新窗口。

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搜索」。

2.1 切換到新窗口

若是咱們要到新的窗口裏面操做,該怎麼作呢?

可使用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)

2.2 切換回原來的窗口

一樣的,若是咱們在新窗口 操做結束後,還要回到原來的窗口,該怎麼辦?

咱們能夠仍然使用上面的方法,依次切入窗口,而後根據標題欄之類的屬性值判斷。

還有更省事的方法。

由於咱們一開始就在原來的窗口裏面,咱們知道進入新窗口操做完後,還要回來,能夠事先保存該老窗口的句柄,使用以下方法:

# 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

經過測試的結果,咱們能夠看到窗口切換了兩次。

相關文章
相關標籤/搜索