带有 Selenium 的 Python:从文件系统拖放到 webdriver?

Posted

技术标签:

【中文标题】带有 Selenium 的 Python:从文件系统拖放到 webdriver?【英文标题】:Python with Selenium: Drag and Drop from file system to webdriver? 【发布时间】:2017-09-08 23:54:48 【问题描述】:

我必须自动化一个网络应用程序,其中包含一个拖放区域,用于从本地文件系统上传文件。我的测试环境是使用 Python 开发的。对于自动化测试,我使用了 Selenium,但是一旦上传区域是 div 标签(没有输入标签 - 我知道这样会很容易),就无法从文件系统中拖动文件。

我阅读了很多不同的文章,但目前没有一篇文章对我有用。需要强调的是,我对使用 AutoIT 不感兴趣,只对带有 selenium 的原生 python 感兴趣。

我发现这个 Selenium: Drag and Drop from file system to webdriver? 看起来很有希望,但是我不知道要适应 Python。

非常感谢您!

【问题讨论】:

文件管理器都是桌面 GUI 应用程序,因此如果 WebDriver 内部没有特殊技巧,则无法使用 Selenium 自动化它们。如果您在 Windows 上,explorer.exe 可以使用 pywinauto 自动化。我的学生将an example that drags-n-drops the file 从explorer.exe 写到Chrome(Google 磁盘)。有帮助吗? 说实话,我很想知道如何在页面中注入一个新的INPUT元素来通过SendKeys接收文件。我知道使用 c# 和 java 是可能的,但是我不知道如何使用 python 来管理它。 【参考方案1】:

这是通过脚本输入注入的技巧的 Python 版本。

JS_DROP_FILE = """
    var target = arguments[0],
        offsetX = arguments[1],
        offsetY = arguments[2],
        document = target.ownerDocument || document,
        window = document.defaultView || window;

    var input = document.createElement('INPUT');
    input.type = 'file';
    input.onchange = function () 
      var rect = target.getBoundingClientRect(),
          x = rect.left + (offsetX || (rect.width >> 1)),
          y = rect.top + (offsetY || (rect.height >> 1)),
          dataTransfer =  files: this.files ;

      ['dragenter', 'dragover', 'drop'].forEach(function (name) 
        var evt = document.createEvent('MouseEvent');
        evt.initMouseEvent(name, !0, !0, window, 0, 0, 0, x, y, !1, !1, !1, !1, 0, null);
        evt.dataTransfer = dataTransfer;
        target.dispatchEvent(evt);
      );

      setTimeout(function ()  document.body.removeChild(input); , 25);
    ;
    document.body.appendChild(input);
    return input;
"""

def drag_and_drop_file(drop_target, path):
    driver = drop_target.parent
    file_input = driver.execute_script(JS_DROP_FILE, drop_target, 0, 0)
    file_input.send_keys(path)

作为drop_target 传递页面上可见的一些元素。

该方法是使用 selenium 的 execute_script 函数调用 javascript 来模拟拖放事件。代码如下:

    selenium 调用 javascript 代码 javascript 创建输入元素并将其附加到 DOM javascript 将处理程序附加到输入,以模拟用户实际放置文件时发生的鼠标事件,即dragenterdragoverdrop。 selenium 使用文件路径更新输入。此时,第 2 步中的处理程序被调用并模拟拖放事件。

【讨论】:

优秀。为我工作。应该是公认的答案。 做这种事的人 当您调用“drag_and_drop_file”时,您为“drop_target”传递了什么值? 为了测试自动化的目的,像@RomanKonoval 的评论一样将元素直接添加到正文中会在收到输入元素时产生小的抖动。更好的方法是获取目标的 parentElement 并直接在那里添加/删除它。 我知道这是一个迟到的评论,但我遇到了类似的问题。我被困在我的代码上几个小时试图找到一个解决方案,直到我找到这个答案。我试过了,它就像一个魅力。感谢您的回答。【参考方案2】:

我知道这可能是一个迟到的答案,但以防万一找到答案的人!

如果您使用 Chrome,请go to this site 下载 Chrome 驱动程序。 (尝试找到你的chrome版本thru this并选择合​​适的)

您还需要做另一件事 我马上给大家看


首先:下载chrome驱动并复制Xpath

第 1 步:转到您想要的站点并复制“拖放”的 fullXPath,右键单击拖放区域,然后点击检查。

请这样做两次,以防它检查正确的位置

第 2 步: 您将看到突出显示的颜色,再次右键单击它们

然后你会发现“copy” -> “copy fullXpath”

最后,让我们编码

等等!!! 还有一个建议,请: 如果您发现粘贴“Xpath”或“文件夹链接”出现问题for example

你可以用''代替""

from selenium import webdriver
driver = webdriver.Chrome('D:\Folder\chromedriver')
driver.get('https://exmaple.com')
drag_&_drop = driver.find_element_by_xpath('paste-the-full-xpath-here')
drag_&_drop.send_keys('D:\Folder\picture.png')
#python 3.9

【讨论】:

以上是关于带有 Selenium 的 Python:从文件系统拖放到 webdriver?的主要内容,如果未能解决你的问题,请参考以下文章

在带有 selenium 的 python 中,如何轮换 IP 地址?

带有 TaskManager 和 selenium 的 ERR_NETWORK_CHANGED

Python selenium 我无法访问带有 iframe 的页面上的链接页面

无法使用带有 BrowserMob-Proxy 的 Python Selenium 脚本捕获 HAR

使用selenium for python从文件夹导入文件

Python Selenium选择带有空格的div类