1. 程式人生 > >解決Selenium報錯:Element is not clickable at point (x, y). Other element would receive the click

解決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()好像也可以實現這個功能,但我試了下不是很好用,大家有興趣可以看看。