今天在寫selenium一個發送郵件腳本時,遇到一些沒有找到頁面元素的錯誤。經過自己反復調試,找原因百度,終於解決了。簡單總結一下吧,原因有以下幾點:
一:Frame控件嵌套,.Frame/Iframe原因定位不到元素:
一般大家經常使用的郵箱算是frame嵌套的典型,通常注冊登錄都是在一個frame控件里面,而且標題正文可能是frame中嵌套iframe,接下里用我今天的腳本為例子(qq郵箱)
可以看到,如果我們要想找到收件人,標題就要先進到第一個Frame控件中,否則就會報錯,但如果還要找到正文元素,就要進入第二個ifame控件中
可以使用 self.driver.switch_to.frame(傳入id或者xpath值)方法進入Frame控件中。注(原來driver.switch_to_frame()這個方法在webdriver3.0中已經不支持了)
值得注意的一點的是:如果我此時我要點擊發送按鈕就需要先退出iframe控件,因為此時發送並不在正文所在的iframe控件當中,因此,無論你怎么定位,也定位不到。
此時就需要用到switch_to.default_content()這個方法。這個方法是無論你在哪一層級的frame控件中,只要調用此方法都會返回原始頁面。如果我要找到發送按鈕,就還要再次進入frame控件中去找
html界面結構如下
就是這個嵌套問題讓我折騰一上午,總結一下吧:遇到多級Frame嵌套問題,一定要先仔細觀察HTML的結構,別着急定位,觀察好結構在往下進行,省的跟我一樣浪費時間。
二:.頁面還沒有加載出來,就對頁面上的元素進行的操作:
這種情況一般說來,可以設置等待,等待頁面顯示之后再操作,這與人手工操作的原理一樣:
1設置等待時間;缺點是需要設置較長的等待時間,案例多了測試就很慢;
2設置等待頁面的某個元素出現,比如一個文本、一個輸入框都可以,一旦指定的元素出現,就可以做操作。
3在調試的過程中可以把頁面的html代碼打印出來,以便分析。
解決方案:
導入時間模塊。(或者利用隱式等待或者顯式等待)
import time
time.sleep(3)
三:利用xpath進行定位:
由於Xpath層級太復雜,容易犯錯。雖然有人說xpath不好,但它真的功能很強大,可以找到父親/祖先,這是其他方式都做不到的,如果遇到定位不到元素不妨試試xpath
解決方案:
1可以使用Firefox的firePath,復制xpath路徑。該方式容易因為層級改變而需要重新編寫過xpath路徑,不建議使用,初學者可以先復制路徑,然后嘗試去修改它。
2提高下寫xpath的水平。
這里推薦一篇文章吧:[selenium+python元素定位方法總結](http://https://www.cnblogs.com/yufeihlf/p/5717291.html)
該博文詳細總結了Xpath的使用,多組合定位一般都能實現定位問題。
如何檢驗編寫的Xpath是否正確?編寫好Xpath路徑,可以直接復制到搜狐瀏覽器的firebug查看html源碼,通過Xpath搜索:如下紅色框,若無報錯,則說明編寫的Xpath路徑沒錯。
find_element_by_xpath("//input[@id='kw']")
(注:如果是動態元素,直接使用xpath進行定位)
四:不可見元素定位
如上百度登錄代碼,通過名稱為tj_login查找的登錄元素,有些是不可見的,所以加一個循環判斷,找到可見元素(is_displayed())點擊登錄即可。