硒.正面有一个窗户

Ant*_*han 3 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");
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

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

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

Flo*_* B. 6

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

但是,您可以通过将窗口移出屏幕来避免此效果:

driver.Manage().Window.Position = new Point(-32000, -32000);
Run Code Online (Sandbox Code Playgroud)

或者在屏幕外启动浏览器:

var options = new ChromeOptions();
options.AddArgument("--window-position=-32000,-32000");
Run Code Online (Sandbox Code Playgroud)

UPDATE

您可以通过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;
    }
}
Run Code Online (Sandbox Code Playgroud)

用法:

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