硒。正面有一个窗户

时间:2018-01-13 20:25:52

标签: c# selenium selenium-webdriver

如果您运行以下代码,那么在循环的每次迭代中,浏览器都会显示在前面并获得焦点。

public class Program
{
  private static void Main()
  {
    var driver = new ChromeDriver();
    driver.Navigate().GoToUrl("https://i.imgur.com/cdA7SBB.jpg");
    for (int i = 0; i < 100; i++)
    {
      var ss = ((ITakesScreenshot)driver).GetScreenshot();
      ss.SaveAsFile("D:/imgs/i.jpg");
    }
  }
}

问题是:为什么会发生这种情况并且可以关闭它?无头的mod不适合。

当Selenium需要保存/读取文件或启动过程时,似乎总会发生这种情况。

2 个答案:

答案 0 :(得分:5)

要截取屏幕截图,chromedriver会激活窗口。这是设计上的,即使在技术上可行,也没有选择可以避免它。 相关来源请查看window_commands.cc

然而,您可以通过将窗口移出屏幕来避免这种影响:

driver.Manage().Window.Position = new Point(-32000, -32000);

或在屏幕外启动浏览器:

var options = new ChromeOptions();
options.AddArgument("--window-position=-32000,-32000");

更新

您可以通过devtool API直接截取屏幕截图来避免激活。这是一个覆盖GetScreenshot的类:

using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Remote;
using JObject = System.Collections.Generic.Dictionary<string, object>;


class ChromeDriverEx : ChromeDriver
{
    public ChromeDriverEx(ChromeOptions options = null) 
        : base(options ?? new ChromeOptions()) {
        var repo = base.CommandExecutor.CommandInfoRepository;
        repo.TryAddCommand("send", new CommandInfo("POST", "/session/{sessionId}/chromium/send_command_and_get_result"));
    }

    public new Screenshot GetScreenshot() {
        object response = Send("Page.captureScreenshot", new JObject {{"format", "png"}, {"fromSurface", true}});
        string base64 = (string)((JObject)response)["data"];
        return new Screenshot(base64);
    }

    protected object Send(string cmd, JObject args) {
        return this.Execute("send",  new JObject {{"cmd", cmd}, {"params", args}}).Value;
    }
}

用法:

var driver = new ChromeDriverEx();
driver.Url = "https://stackoverflow.com";
driver.GetScreenshot().SaveAsFile("/tmp/screenshot.png");
driver.Quit();

答案 1 :(得分:0)

当您通过Navigate().GoToUrl("url")脚本调用 Automation 方法时,您的脚本可能会与网页上的某些元素进行交互。因此,要 Selenium 与这些元素进行互动,Selenium需要关注。因此,打开浏览器显示在前面获得焦点是通过Navigate().GoToUrl("url")实现的默认现象。

现在 Default Mode Headless Mode ChromeOption / {控制{1}} 在初始化FirefoxOptions实例时作为参数传递的类,并将调用WebDriver。因此,Navigate().GoToUrl("url")Navigate().GoToUrl("url")实例控制WebDriverMode of OperationDefault Mode的方式没有影响。

现在,当您尝试从ITakesScreenshot Interface调用该方法时,即ITakesScreenshot.GetScreenshot Method定义为:

Headless Mode

如果Gets a Screenshot object representing the image of the page on the screen. 实例扩展了 WebDriver ,请尽量根据浏览器按优先顺序返回以下内容:

  1. ITakesScreenshot
  2. Entire page
  3. Current window
  4. Visible portion of the current frame
  5. 浏览器失去焦点时可能会出现一些情况。在这种情况下,您可以使用The screenshot of the entire display containing the browser重新获得焦点,如下所示:

    IJavascriptExecutor