拖放功能无法使用

3

我在Chrome浏览器中使用ActionChains动作,特别是drag_and_drop操作无法成功,但我没有发现任何解决方法。

我的情况是,只有将元素拖入到某个字段中,数据表才会出现。如果我试图使用ActionChains进行操作,程序什么也不做并且停滞不前。

这是使用Python的selenium。 我使用的是Chrome 75.0.3770.100版本。

以下是可以重现该情况的示例代码片段:

from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.select import Select
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.webdriver.common.action_chains import ActionChains

import time
import re

### Start Process
# create a new Chrome session
driver = webdriver.Chrome()
driver.implicitly_wait(30)
driver.maximize_window()
driver.get('https://www.w3schools.com/html/html5_draganddrop.asp')


dragged = driver.find_element_by_xpath('//*[@id="drag1"]')
dropped = driver.find_element_by_xpath('//*[@id="div2"]')
ActionChains(driver).drag_and_drop(dragged, dropped).perform()

该代码应该只是将标志从左侧框拖到右侧,但它什么也没做。
编辑: 这里是在shell中返回的内容:
 DevTools listening on ws://127.0.0.1:54994/devtools/browser/a9093d6c-8ee0-4140-84fe-dd3009412fbc
 [14976:20964:0710/120727.552:ERROR:ssl_client_socket_impl.cc(947)] handshake failed; returned -1, SSL error code 1, net_error -100
 [14976:20964:0710/120727.576:ERROR:ssl_client_socket_impl.cc(947)] handshake failed; returned -1, SSL error code 1, net_error -100
 Press any key to continue . . . [14976:20964:0710/120736.634:ERROR:ssl_client_socket_impl.cc(947)]
 handshake failed; returned -1, SSL error code 1, net_error -100

如果它依赖于ondragover和ondrop事件,那么它将无法工作(当前draganddrop操作仅生成mousedown/mouseup)。您需要使用JavaScript生成事件。另请参阅此帖子:https://stackoverflow.com/questions/56604135/why-this-seleniums-drag-and-drop-c-sharp-code-is-not-working-on-chrome/56615037#56615037 - pcalkins
@pcalkins 謝謝,我會編輯帖子並嘗試執行 JavaScript。 - tstaplet
@pcalkins,我无法从https://stackoverflow.com/questions/56604135/why-this-seleniums-drag-and-drop-c-sharp-code-is-not-working-on-chrome/56615037#56615037中获取您的解决方案。我将语法(字符串外部)转换为Python,并尝试使用driver.execute_script(simulateFunction + "\n simulateDragDrop(dragged, dropped);", dragged, dropped)调用它,但它无法识别输入。您能否提供一个答案,展示如何在Python中成功实现这个功能? - tstaplet
我不懂Python。基本上,我在字符串的末尾定义了todrag和todrop元素...(“drag1”和“div2”是问题中W3Cschools页面的特定ID),所以最后两行中,您需要放入您正在拖动和放置的元素的ID...(希望它们有ID...)调用函数保持不变,因为这些变量已经被定义。因此,它将实用程序函数注入两个声明变量的语句中,然后使用这些声明的变量(它们是元素)调用函数。 - pcalkins
所以基本上你不需要那里的args...你只是将脚本作为字符串注入。只修改var定义...函数调用仍然是“simulateDragDrop(toDrag, toDrop);”。如果你愿意,你可以将它们合并成一个字符串。你还应该发布标记,因为这可能不是你需要的。 - pcalkins
1个回答

0

@pcalkins 搞定了!这是可用的代码!我只是将声明变量的字符串中的最后一行移动到函数调用中,以便在不同情况下进行更改。非常感谢!

from selenium import webdriver

#javaScript function to drag and drop
simulateFunction = str("function simulateDragDrop(sourceNode, destinationNode) {\n" +
"    var EVENT_TYPES = {\n" +
"        DRAG_END: 'dragend',\n" +
"        DRAG_START: 'dragstart',\n" +
"        DROP: 'drop'\n" +
"    }\n" +
"\n" +
"    function createCustomEvent(type) {\n" +
"        var event = new CustomEvent(\"CustomEvent\")\n" +
"        event.initCustomEvent(type, true, true, null)\n" +
"        event.dataTransfer = {\n" +
"            data: {\n" +
"            },\n" +
"            setData: function(type, val) {\n" +
"                this.data[type] = val\n" +
"            },\n" +
"            getData: function(type) {\n" +
"                return this.data[type]\n" +
"            }\n" +
"        }\n" +
"        return event\n" +
"    }\n" +
"\n" +
"    function dispatchEvent(node, type, event) {\n" +
"        if (node.dispatchEvent) {\n" +
"            return node.dispatchEvent(event)\n" +
"        }\n" +
"        if (node.fireEvent) {\n" +
"            return node.fireEvent(\"on\" + type, event)\n" +
"        }\n" +
"    }\n" +
"\n" +
"    var event = createCustomEvent(EVENT_TYPES.DRAG_START)\n" +
"    dispatchEvent(sourceNode, EVENT_TYPES.DRAG_START, event)\n" +
"\n" +
"    var dropEvent = createCustomEvent(EVENT_TYPES.DROP)\n" +
"    dropEvent.dataTransfer = event.dataTransfer\n" +
"    dispatchEvent(destinationNode, EVENT_TYPES.DROP, dropEvent)\n" +
"\n" +
"    var dragEndEvent = createCustomEvent(EVENT_TYPES.DRAG_END)\n" +
"    dragEndEvent.dataTransfer = event.dataTransfer\n" +
"    dispatchEvent(sourceNode, EVENT_TYPES.DRAG_END, dragEndEvent)\n" +
"}; ")

### Start Process
# create a new Chrome session
driver = webdriver.Chrome()
driver.implicitly_wait(30)
driver.maximize_window()
driver.get('https://www.w3schools.com/html/html5_draganddrop.asp')

#call javascript dragdrop function
#here, drag1 and div2 are the page-specific IDs of the item to drag and the place to drop it, respectively.
driver.execute_script(simulateFunction + "var toDrag =document.getElementById('drag1'); var toDrop = document.getElementById('div2'); simulateDragDrop(toDrag, toDrop);")

很高兴听到这个!我也传递了自己函数的值...所以在Java中它变成了:""var toDrag =document.getElementById('"+ this.Variable1 + "drag1');..."" - pcalkins

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接