溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

selenium?drag_and_drop不生效如何解決

發(fā)布時(shí)間:2023-03-21 15:59:07 來源:億速云 閱讀:125 作者:iii 欄目:開發(fā)技術(shù)

本篇內(nèi)容主要講解“selenium drag_and_drop不生效如何解決”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實(shí)用性強(qiáng)。下面就讓小編來帶大家學(xué)習(xí)“selenium drag_and_drop不生效如何解決”吧!

做自動(dòng)化時(shí)發(fā)現(xiàn)用drag_and_drop模擬拖拽沒效果,頁面上只能看到元素source閃了一下,但是并沒有拖拽到元素target上(推測可能是我用系統(tǒng)頁面在拖拽時(shí)有個(gè)JS效果,但是drag_and_drop模擬拖拽的時(shí)候執(zhí)行太快沒能觸發(fā)JS,所以沒有把這兩個(gè)元素拖拽到一起)。

通過不斷嘗試,終于解決了,這里記錄一下,希望其他人遇到類似情況時(shí)能有所啟發(fā)。方法1是我嘗試的過程;方法2是我看到的另一種方法,雖然試驗(yàn)了下沒效果,但說不定對其他的拖拽場景是有效的。

方法1:分解drag_and_drop動(dòng)作

從源碼可以看出drag_and_drop的源碼執(zhí)行了兩個(gè)操作,既然直接用drag_and_drop不行,那調(diào)整下這兩個(gè)操作或許可行

    def drag_and_drop(self, source, target):
        """
        Holds down the left mouse button on the source element,
           then moves to the target element and releases the mouse button.
        :Args:
         - source: The element to mouse down.
         - target: The element to mouse up.
        """
        self.click_and_hold(source)
        self.release(target)
        return self

drag_and_drop里有兩個(gè)動(dòng)作:click_and_hold(在source元素上單擊鼠標(biāo)不松開),release(在target元素上釋放點(diǎn)擊狀態(tài)的鼠標(biāo))。中間加一個(gè)鼠標(biāo)移動(dòng)的動(dòng)作是否可行呢?

我把拖拽的流程改成了:

        ActionChains(self.driver).click_and_hold(source).perform()       
        ActionChains(self.driver).move_by_offset(x, y).perform()
        ActionChains(self.driver).release(target).perform()

試驗(yàn)了一下,在執(zhí)行move_by_offset動(dòng)作的時(shí)候能觸發(fā)JS的效果,只不過位移的xy不準(zhǔn)確,觸發(fā)不了另一個(gè)JS,只要計(jì)算好要偏移的位置就好了

最終的實(shí)現(xiàn):

    def drag_and_drop(self):
        source = self.find_element_and_scroll_into_view(source_loc)
        target = self.find_element_and_scroll_into_view(target_loc)
        # 先移動(dòng)一點(diǎn) 觸發(fā)js效果 觸發(fā)后元素變小 重新獲取元素以便能準(zhǔn)確計(jì)算鼠標(biāo)偏移量
        ActionChains(self.driver).click_and_hold(source).move_by_offset(5, 0).perform()
        drag_source = self.find_element(change_source_loc)
 
        x1, x2 = (drag_source.location.get("x"), drag_source.location.get("x") + drag_source.size.get("width"))
        y1, y2 = (drag_source.location.get("y"), drag_source.location.get("y") + drag_source.size.get("height"))
        source_middle_x = (x1 + x2) / 2
        source_middle_y = (y1 + y2) / 2
        x3, x4 = (target.location.get("x"), target.location.get("x") + target.size.get("width"))
        y3, y4 = (target.location.get("y") + 0.5 * target.size.get("height"), target.location.get("y") + target.size.get("height"))
        target_middle_x = (x3 + x4) / 2
        target_middle_y = (y3 + y4) / 2
        x = target_middle_x - source_middle_x
        y = target_middle_y - source_middle_y
 
        ActionChains(self.driver).move_by_offset(x, y).perform()
        ActionChains(self.driver).release(target).perform()

 拖拽效果:

selenium?drag_and_drop不生效如何解決

 方法2:使用seletools解決

雖然我試了下沒效果,但是感覺是有用的,這里一并記錄下。

selenium的drag_and_drop方法在某些場景下無效,這是官方很久就已經(jīng)知道的BUG,只不過沒有在源碼中修復(fù),而是提供了單獨(dú)的包,因?yàn)镈avid Burnes(核心 Selenium 提交者)認(rèn)為拖放錯(cuò)誤是一個(gè)webdriver網(wǎng)絡(luò)驅(qū)動(dòng)問題,在Selenium中提供任何暫時(shí)避開網(wǎng)絡(luò)的方法并不是一個(gè)好主意。

安裝

pip install seletools

使用

from seletools.actions import drag_and_drop
 
source = driver.find_element(xxx)
target = driver.find_element(xxx)
drag_and_drop(driver, source, target)

到此,相信大家對“selenium drag_and_drop不生效如何解決”有了更深的了解,不妨來實(shí)際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI