1. 程式人生 > >【基於Python的Selenium2自動化測試】04 - 模擬126郵箱的登入

【基於Python的Selenium2自動化測試】04 - 模擬126郵箱的登入

首先開啟126郵箱的登入頁面如下:
在這裡插入圖片描述

所以我們要模擬的就是上圖中的郵箱賬號和密碼的填寫,以及登入按鈕的點選事件。

通過Chrome的開發者工具(F12),我們可以看到上述元素的前端程式碼如下:

【郵箱賬號或手機號】

  <div class="u-input box" id="auto-id-1547015266203">
    <label class="u-label f-dn" id="auto-id-1547015266172" style="display: block;">郵箱帳號或手機號</label>
    <input
data-placeholder="郵箱帳號或手機號" name="email" data-type="email" data-loginname="loginEmail" data-required="true" class="j-inputtext dlemail" type="text" autocomplete="off" tabindex="1" spellcheck="false" id="auto-id-1547015266158" placeholder="郵箱帳號或手機號" style="width: 188px;" />
<span class="pr-domain j-prdomain"
style="right: -87px;">
@126.com</span> </div>

【密碼】

  <div class="u-input box" id="auto-id-1547015266205">
    <label class="u-label f-dn" id="auto-id-1547015266181" style="display: block;">密碼</label>
    <input type="password" style="display:none;width:0;height:0;"
/>
<input data-placeholder="密碼" name="password" maxlength="50" data-required="true" class="j-inputtext dlpwd" type="password" autocomplete="new-password" data-max-length="50" tabindex="2" spellcheck="false" id="auto-id-1547015266161" placeholder="密碼" /> <input maxlength="50" data-placeholder="密碼" type="text" id="pwdtext" class="u-pwdtext" placeholder="密碼" /> </div>

【登入按鈕】

  <div class="f-cb loginbox">
   	<a href="javascript:void(0);" id="dologin" data-action="dologin" class="u-loginbtn btncolor tabfocus btndisabled" tabindex="8">&nbsp;&nbsp;</a>
  </div>

【程式碼】

# coding=utf-8
from selenium import webdriver
import time

driver = webdriver.Chrome()
driver.get("http://www.126.com")

#執行郵箱登入操作
driver.find_element_by_name("email").clear()
driver.find_element_by_name("email").send_keys("emailName")
driver.find_element_by_name("password").clear()
driver.find_element_by_name("password").send_keys("passWord")
driver.find_element_by_id("dologin").click()

time.sleep(5)
driver.quit()

執行結果報如下錯誤:

selenium.common.exceptions.NoSuchElementException: Message: Unable to locate element: [name="email"]

網上搜索尋找解決方法:
在做web應用的自動化測試時,定位元素是必不可少的,這個過程經常會碰到定位不到元素的情況(報selenium.common.exceptions.NoSuchElementException),很常見的原因就是Frame/Iframe原因定位不到元素
這個原因很常見,首先要理解下frame的實質,frame中實際上是嵌入了另一個頁面,而 webdriver 每次只能在一個頁面識別,因此需要先定位到相應的frame,對那個頁面裡的元素進行定位
如果iframe有name或id的話,直接使用switch_to_frame("name值")switch_to_frame("id值") ,如果沒有可用 id或者 name時,就需要通過其他的方法先定位到 iframe,再切換進去。。

我們還是通過Chrome開發者工具檢視上述元素,發現在郵箱帳號登入下面果真有下面一行程式碼:

  <iframe name="" frameborder="0" id="x-URS-iframe1547019659690.2905" scrolling="no" style="width: 100%; height: 100%; border: none; background: none;" 
  src="https://passport.126.com/webzj/v1.0.1/pub/index_dl2_new.html?
  cd=https%3A%2F%2Fmimg.127.net%2Findex%2F126%2Fscripts%2F2017%2Fpc%2Fcss%2F&amp;
cf=urs.3edc4a54.css&amp;MGID=1547019659690.2905&amp;wdaId=&amp;pkid=QdQXWEQ&amp;product=mail126">
  </iframe>

也就是說這裡有頁面巢狀問題

我們看到上面的頁面元素,發現上面的iframename屬性為空,雖然有id屬性,但是這個id是動態生成的,每次開啟後面的數字都是不一樣的,所以,這時候我們需要通過採用其他方法先定位到該iframe,然後再切換進去。

【程式碼修改】

# coding=utf-8
from selenium import webdriver
import time

driver = webdriver.Firefox()
driver.get("http://www.126.com")

iframe = driver.find_element_by_xpath("//div[@id='loginDiv']/iframe")
driver.switch_to.frame(iframe)
#執行郵箱登入操作
driver.find_element_by_name("email").clear()
driver.find_element_by_name("email").send_keys("emailName")
driver.find_element_by_name("password").clear()
driver.find_element_by_name("password").send_keys("passWord")
driver.find_element_by_id("dologin").click()

time.sleep(30)

執行結果,還是報錯,如下:

selenium.common.exceptions.NoSuchElementException: Message: Unable to locate element: //div[@id='loginDiv']/iframe

這時,遇到了新的問題,繼續尋找度娘,最後找到了原因:其實是程式在開啟網頁後,進行下一步操作時,frame還未載入進來導致的所以在定位frame元素之前,加一個延時操作,程式就能夠順利繼續下去了

【程式碼繼續修改】

# coding=utf-8
from selenium import webdriver
import time

driver = webdriver.Firefox()
driver.get("http://www.126.com")

time.sleep(1)  # 加一個延時操作,才能定位到下面的iframe
iframe = driver.find_element_by_xpath("//div[@id='loginDiv']/iframe")
driver.switch_to.frame(iframe)
#執行郵箱登入操作
driver.find_element_by_name("email").clear()
driver.find_element_by_name("email").send_keys("emailName")
driver.find_element_by_name("password").clear()
driver.find_element_by_name("password").send_keys("passWord")
driver.find_element_by_id("dologin").click()

time.sleep(3)

執行程式碼後,發現沒有報錯,但是跟我們預想的結果不一樣,沒有直接登入到郵箱裡面,而是出現了一個【是否更換手機號】的登入提示框。如下:
在這裡插入圖片描述

這裡,我不需要更換手機號,直接點選【登入】就可以進入到郵箱裡面了。
但是我們看到這個提示框也是巢狀頁面,通過F12偵錯程式看到如下巢狀程式碼:
在這裡插入圖片描述

解決方法: 先從上一個iframe切回到主文件頁面,然後再從主文件頁面切入到這個新的提示框的iframe,最後再點選這個新的 iframe中的【登入】按鈕即可。

【程式碼繼續修改】

# coding=utf-8
from selenium import webdriver
import time

driver = webdriver.Firefox()
driver.get("http://www.126.com")

time.sleep(1)  # 加一個延時操作,才能定位到下面的iframe
iframe1 = driver.find_element_by_xpath("//div[@id='loginDiv']/iframe")
driver.switch_to.frame(iframe1)
#執行郵箱登入操作
driver.find_element_by_name("email").clear()
driver.find_element_by_name("email").send_keys("emailName")
driver.find_element_by_name("password").clear()
driver.find_element_by_name("password").send_keys("passWord")
driver.find_element_by_id("dologin").click()

driver.switch_to.default_content()  # 切回到主文件頁面
time.sleep(1)  # 這裡不加延時,也定位不到下面iframe中的[登入]按鈕
iframe2 = driver.find_element_by_xpath("//div[@id='loginDiv']/iframe")
driver.switch_to.frame(iframe2)
driver.find_element_by_link_text("登入").click()

點選,執行,終於是我們想要看到的結果了,如下:
在這裡插入圖片描述