解決Selenium報錯:Element is not clickable at point (x, y). Other element would receive the click
用Python寫路由器控制指令碼的時候遇到這個問題,Selenium提示如下:
Message: Element is not clickable at point (1191.5, 143). Other element would receive the click: <div style="display: block; width: 100%; height: 911px; opacity: 0.15;" id="lock_div"></div>
翻譯過來的字面意思大概是:元素在座標(1191.5,143)處不可進行點選操作,其他元素或許會收到這個點選操作。
我這裡的操作是這樣的:使用Selenium進行路由器引數配置,配置完成後儲存,接著點選返回按鈕。
問題就出現在點選返回按鈕這個操作處,操作介面如圖:
我第一反應是,圖中的彈窗(“請稍後...”)需要一定時間完成,為了保證下一步返回按鈕元素能被可靠點選,應當加入等待,於是我在點選前加上:
WebDriverWait(self.browser, 50).until(EC.element_to_be_clickable((By.CLASS_NAME, "return_a")))
但是這樣做並沒有效果,我在這條語句執行前後加上了時間戳,發現根本沒有一點時間間隔:
time1: 2017-06-20 20:30:45
time2: 2017-06-20 20:30:45
也就是說,出現彈窗後,實際上這個按鈕是clickable的,所以這樣等待沒用。
那麼為什麼會不能點選呢?由於我並不熟悉前端技術,我只能猜測可能是這個彈窗介面遮擋住了我的按鈕,導致無法點選,順著這個思路,那麼我應該等待彈窗顯示結束。
簡單的等待方法就是直接採用time.sleep()方法進行延時,但這種方法比較土,等待時間並不精確,於是我想用一種更加優雅的方式。
經過查詢,我發現彈窗有如下html標籤:
<div style="left: 805.5px; top: 277px; display: none;" id="message_layer"> <div id="msg_type" class="success"></div> <div id="msg" class="word">設定成功</div> </div>
div標籤的display屬性在彈窗期間等於block,表示彈窗可見,而彈窗前和結束後會變為none,彈窗被隱藏。
那麼程式碼就很好寫了,只要等待這個div的display屬性變為none就代表配置結束了,正好可以利用Selenium中的is_displayed()方法:
from time import sleep
msg_24g = self.browser.find_element_by_id("message_layer")
while msg_24g.is_displayed():
sleep(1)
至此,問題得到了解決。
另外expected_conditions裡面有個方法is_visibility()好像也可以實現這個功能,但我試了下不是很好用,大家有興趣可以看看。