当前位置: 首页 > 知识库问答 >
问题:

如何使用远程selenium WebDriver下载文件?

满俊楠
2023-03-14

我正在使用远程seleniumwebdriver来执行一些测试。然而,在某个时候,我需要下载一个文件并检查其内容。

我使用远程webdriver如下(在Python中):

PROXY = ...

prefs = {
    "profile.default_content_settings.popups":0,
    "download.prompt_for_download": "false",
    "download.default_directory": os.getcwd(),
}
chrome_options = Options()
chrome_options.add_argument("--disable-extensions")
chrome_options.add_experimental_option("prefs", prefs)

webdriver.DesiredCapabilities.CHROME['proxy'] = {
  "httpProxy":PROXY,
  "ftpProxy":PROXY,
  "sslProxy":PROXY,
  "noProxy":None,
  "proxyType":"MANUAL",
  "class":"org.openqa.selenium.Proxy",
  "autodetect":False
}
driver = webdriver.Remote(
        command_executor='http://aaa.bbb.ccc:4444/wd/hub',
        desired_capabilities=DesiredCapabilities.CHROME)

使用“正常”的webdriver,我可以在本地计算机上毫无问题地下载文件。然后我可以使用测试代码来验证下载文件的内容(可以根据测试参数而改变)。它不是对下载本身的测试,但我需要一种方法来验证生成文件的内容...

但是如何使用远程WebDriver来实现呢?我在任何地方都没有找到任何有用的东西...

共有1个答案

双恩
2023-03-14

Selenium API没有提供在远程计算机上下载文件的方法。

但它仍然可以单独使用Selenium,这取决于浏览器。

使用Chrome时,可以通过导航Chrome:/downloads/列出下载的文件,并在页面中使用注入的检索下载的文件:

from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
import os, time, base64


def get_downloaded_files(driver):

  if not driver.current_url.startswith("chrome://downloads"):
    driver.get("chrome://downloads/")

  return driver.execute_script( \
    "return downloads.Manager.get().items_   "
    "  .filter(e => e.state === 'COMPLETE')  "
    "  .map(e => e.filePath || e.file_path); " )


def get_file_content(driver, path):

  elem = driver.execute_script( \
    "var input = window.document.createElement('INPUT'); "
    "input.setAttribute('type', 'file'); "
    "input.hidden = true; "
    "input.onchange = function (e) { e.stopPropagation() }; "
    "return window.document.documentElement.appendChild(input); " )

  elem._execute('sendKeysToElement', {'value': [ path ], 'text': path})

  result = driver.execute_async_script( \
    "var input = arguments[0], callback = arguments[1]; "
    "var reader = new FileReader(); "
    "reader.onload = function (ev) { callback(reader.result) }; "
    "reader.onerror = function (ex) { callback(ex.message) }; "
    "reader.readAsDataURL(input.files[0]); "
    "input.remove(); "
    , elem)

  if not result.startswith('data:') :
    raise Exception("Failed to get file content: %s" % result)

  return base64.b64decode(result[result.find('base64,') + 7:])



capabilities_chrome = { \
    'browserName': 'chrome',
    # 'proxy': { \
     # 'proxyType': 'manual',
     # 'sslProxy': '50.59.162.78:8088',
     # 'httpProxy': '50.59.162.78:8088'
    # },
    'goog:chromeOptions': { \
      'args': [
      ],
      'prefs': { \
        # 'download.default_directory': "",
        # 'download.directory_upgrade': True,
        'download.prompt_for_download': False,
        'plugins.always_open_pdf_externally': True,
        'safebrowsing_for_trusted_sources_enabled': False
      }
    }
  }

driver = webdriver.Chrome(desired_capabilities=capabilities_chrome)
#driver = webdriver.Remote('http://127.0.0.1:5555/wd/hub', capabilities_chrome)

# download a pdf file
driver.get("https://www.mozilla.org/en-US/foundation/documents")
driver.find_element_by_css_selector("[href$='.pdf']").click()

# list all the completed remote files (waits for at least one)
files = WebDriverWait(driver, 20, 1).until(get_downloaded_files)

# get the content of the first file remotely
content = get_file_content(driver, files[0])

# save the content in a local file in the working directory
with open(os.path.basename(files[0]), 'wb') as f:
  f.write(content)
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
import os, time, base64

def get_file_names_moz(driver):
  driver.command_executor._commands["SET_CONTEXT"] = ("POST", "/session/$sessionId/moz/context")
  driver.execute("SET_CONTEXT", {"context": "chrome"})
  return driver.execute_async_script("""
    var { Downloads } = Components.utils.import('resource://gre/modules/Downloads.jsm', {});
    Downloads.getList(Downloads.ALL)
      .then(list => list.getAll())
      .then(entries => entries.filter(e => e.succeeded).map(e => e.target.path))
      .then(arguments[0]);
    """)
  driver.execute("SET_CONTEXT", {"context": "content"})

def get_file_content_moz(driver, path):
  driver.execute("SET_CONTEXT", {"context": "chrome"})
  result = driver.execute_async_script("""
    var { OS } = Cu.import("resource://gre/modules/osfile.jsm", {});
    OS.File.read(arguments[0]).then(function(data) {
      var base64 = Cc["@mozilla.org/scriptablebase64encoder;1"].getService(Ci.nsIScriptableBase64Encoder);
      var stream = Cc['@mozilla.org/io/arraybuffer-input-stream;1'].createInstance(Ci.nsIArrayBufferInputStream);
      stream.setData(data.buffer, 0, data.length);
      return base64.encodeToString(stream, data.length);
    }).then(arguments[1]);
    """, path)
  driver.execute("SET_CONTEXT", {"context": "content"})
  return base64.b64decode(result)

capabilities_moz = { \
    'browserName': 'firefox',
    'marionette': True,
    'acceptInsecureCerts': True,
    'moz:firefoxOptions': { \
      'args': [],
      'prefs': {
        # 'network.proxy.type': 1,
        # 'network.proxy.http': '12.157.129.35', 'network.proxy.http_port': 8080,
        # 'network.proxy.ssl':  '12.157.129.35', 'network.proxy.ssl_port':  8080,      
        'browser.download.dir': '',
        'browser.helperApps.neverAsk.saveToDisk': 'application/octet-stream,application/pdf', 
        'browser.download.useDownloadDir': True, 
        'browser.download.manager.showWhenStarting': False, 
        'browser.download.animateNotifications': False, 
        'browser.safebrowsing.downloads.enabled': False, 
        'browser.download.folderList': 2,
        'pdfjs.disabled': True
      }
    }
  }

# launch Firefox
# driver = webdriver.Firefox(capabilities=capabilities_moz)
driver = webdriver.Remote('http://127.0.0.1:5555/wd/hub', capabilities_moz)

# download a pdf file
driver.get("https://www.mozilla.org/en-US/foundation/documents")
driver.find_element_by_css_selector("[href$='.pdf']").click()

# list all the downloaded files (waits for at least one)
files = WebDriverWait(driver, 20, 1).until(get_file_names_moz)

# get the content of the last downloaded file
content = get_file_content_moz(driver, files[0])

# save the content in a local file in the working directory
with open(os.path.basename(files[0]), 'wb') as f:
  f.write(content)
 类似资料:
  • 问题内容: 是否可以使用cURL部分下载远程文件?假设远程文件的实际文件大小为1000 KB。如何仅下载其中的前500 KB? 问题答案: 您还可以使用php-curl扩展名设置range标头参数。 但是如前所述,如果服务器不遵循该标头而是发送整个文件,则curl将下载所有文件。例如,http: //www.php.net忽略标题。但是,您可以(另外)设置一个写函数回调,并在收到更多数据时中止请求

  • 我是selenium的新手,我想使用selenium chrome Web驱动程序在特定的自定义文件夹中下载文件。默认情况下,该文件正在浏览器指定的下载路径中下载。任何一个建议在C#Selenium的自定义路径中下载文件的最佳解决方案。

  • 我想从远程机器上做一个wget JDK8。那有可能吗?由于链接一旦我同意许可,下载一个HTML文件,而不是64位rpm http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html

  • 我正在编写一个测试,以检查文件是否可以从特定网页下载,并希望它能够在本地和远程运行(即通过Selenium grid在节点上运行)。在有人把我链接到“你真的需要下载文件吗?”文章,我已经设法下载并检查了文件,我只需要在测试完成后删除它的方法。只需调用或类似工具只能在本地工作(据我所知),所以我不能用它从节点机器上删除文件。我知道这个班是但是我找不到任何使用说明。 有谁能提供比“在节点机器上运行脚本

  • 问题内容: 我正在尝试获取下载链接并下载文件。 我有一个包含以下链接的日志文件: 我有这样的代码: 到目前为止,我不知道如何获取下载链接并下载它。可以使用selenium下载文件吗? 问题答案: 根据文档,您应该配置为自动下载具有指定内容类型的文件。这是在txt文件中使用第一个URL的示例,该文件将文件保存在当前目录中: 注意,我也简化了xpath。

  • 我想用php从我的服务器下载文件。我搜索了谷歌,在这里找到了答案。这个答案表明我必须为此编写这些代码。 但我能做到这一点,只需这两行: 那么,我为什么还要像上面的代码那样多写几行呢?