【问题标题】:Can Selenium WebDriver open browser windows silently in the background?Selenium WebDriver 可以在后台静默打开浏览器窗口吗?
【发布时间】:2013-04-17 07:43:11
【问题描述】:

我有一个 Selenium 测试套件,它运行许多测试,并且在每个新测试中,它都会在我打开的任何其他窗口之上打开一个浏览器窗口。在本地环境中工作时非常不和谐。有没有办法告诉 Selenium 或 OS (Mac) 在后台打开窗口?

【问题讨论】:

  • 如果您在代码中使用driver = webdriver.Firefox() ,请在此处按照我的回答:*.com/a/23898148/1515819
  • @StéphaneBruckert Chrome 有类似的东西吗?
  • *.com/a/48775203/1207193 是 2020 GoogleChrome Windows 的有效解决方案

标签: selenium selenium-webdriver webdriver selenium-grid


【解决方案1】:

有几种方法,但它不是简单的“设置配置值”。除非你投资一个不适合每个人要求的无头浏览器,否则它有点像 hack:

How to hide Firefox window (Selenium WebDriver)?

Is it possible to hide the browser in Selenium RC?

您可以“假设”,将一些参数传入 Chrome,具体来说:--no-startup-window

请注意,对于某些浏览器,尤其是 Internet Explorer,如果不让其在焦点上运行会损害您的测试。

您还可以使用AutoIt 破解一下,以便在窗口打开后隐藏它。

【讨论】:

  • "--no-startup-window" 现已弃用
  • 确实,使用“--headless”而不是“--no-startup-window”,我已经确认它适用于 Mac 和 Chrome v80
  • (无头打开 Chrome,如上面评论中所述,请参阅下面的答案)
【解决方案2】:

在 Windows 上你可以使用 win32gui:

import win32gui
import win32con
import subprocess

class HideFox:
    def __init__(self, exe='firefox.exe'):
        self.exe = exe
        self.get_hwnd()

    def get_hwnd(self):
      win_name = get_win_name(self.exe)
      self.hwnd = win32gui.FindWindow(0,win_name)

    def hide(self):
        win32gui.ShowWindow(self.hwnd, win32con.SW_MINIMIZE)
        win32gui.ShowWindow(self.hwnd, win32con.SW_HIDE)

    def show(self):
        win32gui.ShowWindow(self.hwnd, win32con.SW_SHOW)
        win32gui.ShowWindow(self.hwnd, win32con.SW_MAXIMIZE)

def get_win_name(exe):
    ''' Simple function that gets the window name of the process with the given name'''
    info = subprocess.STARTUPINFO()
    info.dwFlags |= subprocess.STARTF_USESHOWWINDOW
    raw = subprocess.check_output('tasklist /v /fo csv', startupinfo=info).split('\n')[1:-1]
    for proc in raw:
        try:
            proc = eval('[' + proc + ']')
            if proc[0] == exe:
                return proc[8]
        except:
            pass
    raise ValueError('Could not find a process with name ' + exe)

例子:

hider = HideFox('firefox.exe') # Can be anything, e.q., phantomjs.exe, notepad.exe, etc.
# To hide the window
hider.hide()
# To show again
hider.show()

但是,此解决方案存在一个问题 - 使用 send_keys 方法会显示窗口。您可以使用不显示窗口的 JavaScript 来处理它:

def send_keys_without_opening_window(id_of_the_element, keys)
    YourWebdriver.execute_script("document.getElementById('" + id_of_the_element + "').value = '" + keys + "';")

【讨论】:

    【解决方案3】:

    在 *nix 上,您还可以运行 Xvfb 之类的无头 X Window 服务器并将 DISPLAY 环境变量指向它:

    Fake X server for testing?

    【讨论】:

      【解决方案4】:

      如果您在 Python 中使用 Selenium Web 驱动程序,则可以使用 PyVirtualDisplay,它是 Xvfb 和 Xephyr 的 Python 包装器。

      PyVirtualDisplay 需要 Xvfb 作为依赖项。在Ubuntu,先安装Xvfb:

      sudo apt-get install xvfb
      

      然后从PyPI安装PyVirtualDisplay:

      pip install pyvirtualdisplay
      

      使用 PyVirtualDisplay 以无头模式在 Python 中使用 Selenium 脚本示例:

          #!/usr/bin/env python
      
          from pyvirtualdisplay import Display
          from selenium import webdriver
      
          display = Display(visible=0, size=(800, 600))
          display.start()
      
          # Now Firefox will run in a virtual display.
          # You will not see the browser.
          browser = webdriver.Firefox()
          browser.get('http://www.google.com')
          print browser.title
          browser.quit()
      
          display.stop()
      

      编辑

      最初的答案是在 2014 年发布的,现在我们正处于 2018 年的风口浪尖。与其他一切一样,浏览器也在进步。 Chrome 现在有一个完全无头的版本,无需使用任何第三方库来隐藏 UI 窗口。示例代码如下:

          from selenium import webdriver
          from selenium.webdriver.chrome.options import Options
      
          CHROME_PATH = '/usr/bin/google-chrome'
          CHROMEDRIVER_PATH = '/usr/bin/chromedriver'
          WINDOW_SIZE = "1920,1080"
      
          chrome_options = Options()
          chrome_options.add_argument("--headless")
          chrome_options.add_argument("--window-size=%s" % WINDOW_SIZE)
          chrome_options.binary_location = CHROME_PATH
      
          driver = webdriver.Chrome(executable_path=CHROMEDRIVER_PATH,
                                    chrome_options=chrome_options
                                   )
          driver.get("https://www.google.com")
          driver.get_screenshot_as_file("capture.png")
          driver.close()
      

      【讨论】:

      • 它适用于 Mac OSX 吗?
      • 如果您使用的是 Ubuntu 并且您的测试套件使用 Python,那就太好了
      • 这在 Java 中可行吗?
      • 不推荐使用 chrome_options,现在只是选项
      【解决方案5】:

      我建议使用PhantomJS。欲了解更多信息,您可以访问Phantom Official Website

      据我所知,PhantomJS 仅适用于 Firefox...

      下载 PhantomJs.exe 后,您需要将其导入到您的项目中,如下图 PhantomJS 所示。

      我把我的放在里面了:commonLibraryphantomjs.exe

      现在您在 Selenium 代码中要做的就是更改行

      browser = webdriver.Firefox()
      

      类似

      import os
      path2phantom = os.getcwd() + "\common\Library\phantomjs.exe"
      browser = webdriver.PhantomJS(path2phantom)
      

      PhantomJS 的路径可能会有所不同...随心所欲改变 :)

      这个技巧对我有用,我很确定它也对你有用;)

      【讨论】:

      • 虽然此链接可能会回答问题,但最好在此处包含答案的基本部分并提供链接以供参考。如果链接页面发生更改,仅链接的答案可能会失效
      • PhantomJS 将于 2020 年 11 月停产。请参阅上面@Amistad 的回答,了解 Google Chrome 的无头模式。
      【解决方案6】:

      这是一个适合我的 .NET 解决方案:

      http://phantomjs.org/download.html 下载 PhantomJS。

      从下载文件夹中的 bin 文件夹中复制 .exe 文件并将其粘贴到 Visual Studio 项目的 bin 调试/发布文件夹中。

      添加这个使用

      using OpenQA.Selenium.PhantomJS;
      

      在您的代码中,像这样打开驱动程序:

      PhantomJSDriver driver = new PhantomJSDriver();
      using (driver)
      {
         driver.Navigate().GoToUrl("http://testing-ground.scraping.pro/login");
         // Your code here
      }
      

      【讨论】:

      • PhantomJS 自 2020 年 11 月起停产。请参阅上面@Amistad 的回答,了解 Google Chrome 的无头模式
      【解决方案7】:

      Chrome 57 有一个选项可以传递 --headless 标志,这会使窗口不可见。

      此标志与 --no-startup-window 不同,因为最后一个不启动窗口。正如this page 所说,它用于托管后台应用程序。

      将标志传递给 Selenium webdriver (ChromeDriver) 的 Java 代码:

      ChromeOptions options = new ChromeOptions();
      options.addArguments("--headless");
      ChromeDriver chromeDriver = new ChromeDriver(options);
      

      【讨论】:

      【解决方案8】:

      如果要在没有任何浏览器的情况下运行,可以在 headless 模式下运行。

      我向你展示一个现在对我有用的 Python 示例

      from selenium import webdriver
      
      
      options = webdriver.ChromeOptions()
      options.add_argument("headless")
      self.driver = webdriver.Chrome(executable_path='/Users/${userName}/Drivers/chromedriver', chrome_options=options)
      

      我还在 Google 官方网站 https://developers.google.com/web/updates/2017/04/headless-chrome 中添加了更多关于此的信息

      【讨论】:

        【解决方案9】:

        从 Chrome 57 开始,你就有了无头论点:

        var options = new ChromeOptions();
        options.AddArguments("headless");
        using (IWebDriver driver = new ChromeDriver(options))
        {
            // The rest of your tests
        }
        

        Chrome 的 headless 模式的性能比 UI 版本好 30.97%。另一个无头驱动程序 PhantomJS 的性能比 Chrome 的无头模式好 34.92%。

        PhantomJSDriver

        using (IWebDriver driver = new PhantomJSDriver())
        {
             // The rest of your test
        }
        

        Mozilla Firefox 的 headless 模式的性能比 UI 版本高 3.68%。这是令人失望的,因为 Chrome 的无头模式比 UI 模式的时间快了 30% 以上。另一个无头驱动程序 PhantomJS 比 Chrome 的无头模式好 34.92%。令我惊讶的是,Edge 浏览器击败了所有这些。

        var options = new FirefoxOptions();
        options.AddArguments("--headless");
        {
            // The rest of your test
        }
        

        这在 Firefox 57+ 中可用

        Mozilla Firefox 的 headless 模式的性能比 UI 版本高 3.68%。这是令人失望的,因为 Chrome 的无头模式比 UI 模式的时间快了 30% 以上。另一个无头驱动程序 PhantomJS 比 Chrome 的无头模式好 34.92%。令我惊讶的是,Edge 浏览器击败了所有这些。

        注意:PhantomJS 不再维护!

        【讨论】:

          【解决方案10】:

          它可能在选项中。这是相同的 Java 代码。

                  ChromeOptions chromeOptions = new ChromeOptions();
                  chromeOptions.setHeadless(true);
                  WebDriver driver = new ChromeDriver(chromeOptions);
          

          【讨论】:

            【解决方案11】:

            如果您使用的是 Ubuntu (Gnome),一种简单的解决方法是安装 Gnome 扩展自动移动窗口:https://extensions.gnome.org/extension/16/auto-move-windows/

            然后将浏览器(例如 Chrome)设置为另一个工作区(例如 Workspace 2)。浏览器将在其他工作区静默运行,不再打扰您。您仍然可以在工作区中使用 Chrome,而不会受到任何干扰。

            【讨论】:

              【解决方案12】:

              我的 chromedriver 使用 Python 时遇到了同样的问题,options.add_argument("headless") 对我不起作用,但后来我意识到如何解决它,所以我把它带入了代码下面:

              opt = webdriver.ChromeOptions()
              opt.arguments.append("headless")
              

              【讨论】:

                【解决方案13】:

                这是一个简单的Node.js 解决方案,适用于 Selenium 的新版本 4.x(也可能是 3.x)。

                const { Builder } = require('selenium-webdriver')
                const chrome = require('selenium-webdriver/chrome');
                
                let driver = await new Builder().forBrowser('chrome').setChromeOptions(new chrome.Options().headless()).build()
                
                await driver.get('https://example.com')
                

                火狐

                const { Builder } = require('selenium-webdriver')
                const firefox = require('selenium-webdriver/firefox');
                
                let driver = await new Builder().forBrowser('firefox').setFirefoxOptions(new firefox.Options().headless()).build()
                
                await driver.get('https://example.com')
                

                整个事情只是在后台运行。这正是我们想要的。

                【讨论】:

                • 这个对我有用,谢谢
                【解决方案14】:

                如果您使用的是 Google Chrome 驱动程序,您可以使用这个非常简单的代码(它对我有用):

                from selenium import webdriver
                from selenium.webdriver.chrome.options import Options
                
                chrome_options = Options()
                chrome_options.add_argument("--headless")
                driver = webdriver.Chrome('chromedriver2_win32/chromedriver.exe', options=chrome_options)
                driver.get('https://www.anywebsite.com')
                

                【讨论】:

                  【解决方案15】:

                  我在 Windows 中将这段代码用于 Firefox 并得到了答案(参考 here):

                  from selenium import webdriver
                  from selenium.webdriver.firefox.options import Options
                  
                  Options = Options()
                  Options.headless = True
                  
                  Driver = webdriver.Firefox(options=Options, executable_path='geckodriver.exe')
                  Driver.get(...)
                  ...
                  

                  但我没有针对其他浏览器进行测试。

                  【讨论】:

                  • 问题已经回答,作者已经批准了答案。
                  • 我为其他会看到这篇文章的人回答了
                  • 感谢您为我们提供 Firefox 替代方案
                  • 也可以在 chrome 中使用!
                  • 像魅力一样工作!
                  【解决方案16】:

                  实现此目的的一种方法是在无头模式下运行浏览器。这样做的另一个优点是测试执行速度更快。

                  请在下面找到代码在 Chrome 浏览器中设置无头模式。

                  package chrome;
                  
                  public class HeadlessTesting {
                  
                      public static void main(String[] args) throws IOException {
                          System.setProperty("webdriver.chrome.driver",
                                  "ChromeDriverPath");
                          ChromeOptions options = new ChromeOptions();
                          options.addArguments("headless");
                          options.addArguments("window-size=1200x600");
                          WebDriver driver = new ChromeDriver(options);
                          driver.get("https://contentstack.built.io");
                          driver.get("https://www.google.co.in/");
                          System.out.println("title is: " + driver.getTitle());
                          File scrFile = ((TakesScreenshot) driver)
                                  .getScreenshotAs(OutputType.FILE);
                          FileUtils.copyFile(scrFile, new File("pathTOSaveFile"));
                          driver.quit();
                      }
                  }
                  

                  【讨论】:

                    【解决方案17】:

                    只需添加一个简单的“无头”选项参数即可。

                    from selenium import webdriver
                    
                    options = webdriver.ChromeOptions()
                    options.add_argument("--headless")
                    driver = webdriver.Chrome("PATH_TO_DRIVER", options=options)
                    

                    【讨论】:

                      【解决方案18】:

                      使用它...

                      from selenium import webdriver
                      from selenium.webdriver.chrome.options import Options
                      
                      options = Options()
                      options.headless = True
                      driver = webdriver.Chrome(CHROMEDRIVER_PATH, chrome_options=options)
                      

                      【讨论】:

                      • 解释一下。您可以edit your answer没有“编辑:”、“更新:”或类似内容)。
                      • 里面有什么?蟒蛇?