可能的原因如下:
一、頁面沒加載好
解決方法:
添加等待方法,如: time.sleep()
二、頁面提交需要等待給數據后台
解決方法:
添加等待方法,如: time.sleep()
三、瀏覽器沒有以最大化方式打開,導致元素被隱藏,定位不到
解決方法:
將網頁最大化: driver.maximize_window()
如果屏幕比例固定,分辨率有限,通過網頁最大化也沒辦法解決的話,可以通過執行JS方法來實現。
browser.execute_script('window.scrollBy(200,0)') #此處(200,0)為網頁偏移坐標,200為橫坐標,0為縱坐標
#window.scrollBy()為JS方法#
四、網頁中存在多個frame框架,所定位的元素不在當前frame中。所以盡管元素明明看起來是定位正確的,但是點擊無效。
frame框架作用:frame對象代表一個HTML框架,frame就是一個子窗口,在里面可以加載網頁,內部子窗口進行刷新的時候,不會影響外部窗口。對於嵌套多個frame的頁面,操作時需要層層跳轉,跳到元素所在的frame。
frame標簽有frameset、frame、iframe三種,frameset與其他普通標簽一樣,不會影響元素的定位;而frame與iframe的切換方法是一樣的。
frame 下是個獨立的HTML文件:
解決方法:可以利用selenium中的switch_to.frame()方法來實現frame之間的跳轉。
具體操作如下:
1.如何對frame進行切換?
利用switch_to.frame()方法來進行切換。
switch_to.frame(reference)
reference是傳入的參數,用來定位frame,可以是id,name,tag name等。假設有下面HTML代碼:
<html lang="en"> <head> <title>FrameTest</title> </head> <body> <iframe src="myframe.html" id="frame1" name="myframe"></iframe> </body> </html>
則想要切換到上述iframe的方法有:
driver.switch_to.frame(0) #用frame的index定位,第一個是0 driver.switch_to.frame("frame1") #用frame的id來定位 driver.switch_to.frame("myframe") #用name來定位 driver.switch_to.frame(driver.find_element_by_tag_name("iframe")) #用iframe對應的tag name來定位 driver.switch_to_frame(driver.find_element_by_xpath("//iframe[contains(@src,'myframe')]")) #利用xpath來定位
2.如何從子frame切換回主文檔?
切換到子frame后就無法再對主文檔元素進行操作了,所以要切換回主文檔。方法為:driver.switch_to.default_content()
driver.switch_to.default_content()
3.多層frame如何切換?
如果有多層frame要逐層進行切換,例如下列多個frame嵌套的HTML代碼:
<html> <iframe id="frame1"> <iframe id="frame2" / > </iframe> </html>
(1)從主文檔切換到frame 2:
driver.switch_to.frame('frame1') #先從主文檔切換到frame1
driver.switch_to.frame('frame2') #再從frame1切換到frame2
(2)從frame2切回到frame1:
從frame2再切回frame1,這里selenium給我們提供了一個方法能夠從子frame切回到父frame,而不用我們切回主文檔再切進來。
driver.switch_to.parent_frame() # 如果當前已是主文檔,則無效果
有了parent_frame()這個相當於后退的方法,我們可以隨意切換不同的frame,隨意的跳來跳去了。
總結下,遇到frame跳轉問題,利用以下三個方法便可以搞定:
driver.switch_to.frame(reference) driver.switch_to.parent_frame() driver.switch_to.default_content()
五、元素屬性為動態屬性,看着定位已經正確,但是隨着鼠標點擊位置不同,元素的屬性發生變化。
例如下面這個頁面的目錄的class屬性就隨着該元素是否被點擊而發生變化:
解決方法:換元素的另一個固定屬性來進行定位。
六、頁面元素在頁面打開的時候被其他彈出窗口擋住。
解決方法:添加關閉彈出窗口步驟。
七、目標元素在瀏覽器的其他頁面窗口中。
selenium默認操作窗口是腳本打開的起始窗口,如果想要切換到其他窗口,可以利用 driver.switch_to.window(windowhandle)方法來實現,windowhandle參數為瀏覽器的窗口句柄。
可以利用driver.window_handles方法來獲取當前瀏覽器的所有窗口句柄。
例如,切換到百度網頁窗口:
1 for handle in driver.window_handles: #當前瀏覽器所有窗口句柄列表 2 driver.switch_to.window(handle) #挨個進行窗口切換 3 title = driver.title #判斷窗口title 4 if '百度一下,你就知道' in title: 5 print('進入百度網頁') 6 break
可以利用一個網頁的特征屬性來判斷是否正確進入了該網頁,如:title,url,特殊元素等。
附:switch_to.handles(windowhandle)使用方法:
1 handles = driver.window_handles #獲取當前瀏覽器的所有窗口句柄 2 driver.switch_to.window(handles[-1]) #切換到最新打開的窗口 3 driver.switch_to.window(handles[0]) #切換到最開始打開的窗口
如何獲取當前網頁句柄?
driver.current_window_handle