无头Chrome下Selenium测试失败

12

我正在尝试使用无头 Chrome 运行我的 Selenium 测试自动化,以便我可以将其移动到 TeamCity。但是我没有成功。当我运行它时,Chrome 确实似乎是以无头模式运行的(没有浏览器弹出),但是我得到了一个 NoSuchElementException。在非无头模式下运行时,自动化按预期工作。拍摄的快照只显示一个白色矩形。

我已经广泛地研究了这个问题,但我还没有找到适合我的解决方案。似乎这个问题在https://bugs.chromium.org/p/chromedriver/issues/detail?id=476中报告过,但已被标记为已修复。我认为问题可能是错误的 chromedriver 或者是错误的 chromedriver/selenium 组合,但我已经尝试了各种组合,都没有成功。

我正在使用:

  • selenium-java 3.6.0
  • chromedriver 2.33.506120
  • Windows 7 Enterprise Service Pack1, 64-bit

我的代码是:

...
ChromeOptions headlessOptions = new ChromeOptions();
headlessOptions.addArguments("--start-maximized");
headlessOptions.addArguments("--headless");
driver = new ChromeDriver(headlessOptions);
driver.get(url);
WebElement usernameTextfield = driver.findElement(By.cssSelector(".input.username"));
...

输出结果为:

Starting ChromeDriver 2.33.506120 (e3e53437346286c0bc2d2dc9aa4915ba81d9023f) on port 41402
Only local connections are allowed.
Nov 01, 2017 10:22:51 AM org.openqa.selenium.remote.ProtocolHandshake createSession
INFO: Detected dialect: OSS

org.openqa.selenium.NoSuchElementException: no such element: Unable to locate element: {"method":"css selector","selector":".input.username"}
  (Session info: headless chrome=62.0.3202.75)
  (Driver info: chromedriver=2.33.506120 (e3e53437346286c0bc2d2dc9aa4915ba81d9023f),platform=Windows NT 6.1.7601 SP1 x86_64) (WARNING: The server did not provide any stacktrace information)
Command duration or timeout: 0 milliseconds

这导致我无法将我的测试自动化作为我们CI的一部分包含,因此非常感谢任何帮助。


2
尝试在无头浏览器中调试网站,看看元素是否确实丢失。请参阅此线程以获取有关调试的帮助 https://dev59.com/TqTja4cB1Zd3GeqPINvC#46018351 - Tarun Lalwani
Chrome似乎可以无界面运行(没有浏览器弹出)- 你对无头浏览器有什么期望?!?! url是什么?它是https协议吗?并且它使用自签名证书吗? - SiKing
2
检查证书是由浏览器完成的,而不是服务器。如果您在(失败的)测试中截取屏幕截图,则只会得到空白页(如您所确认的)。 Chrome-headless目前不允许忽略错误的证书。Chrome-GUI可以。请参见https://bugs.chromium.org/p/chromium/issues/detail?id=721739。 - SiKing
你说的“不可见”的“不”是正确的。;) 抱歉,是我的错。 - SiKing
@SiKing 谢谢。我非常确定你找到了问题所在。我会和我们的开发人员讨论一下。 - dstaraster
显示剩余2条评论
8个回答

10

这是对我有效的方法:

var chromeOptions = new ChromeOptions();                        
chromeOptions.AddArguments("--headless");
chromeOptions.AddArguments("--disable-gpu");
chromeOptions.AddArguments("--window-size=1280,800");
chromeOptions.AddArguments("--allow-insecure-localhost");

//specifically this line here :)
chromeOptions.AddAdditionalCapability("acceptInsecureCerts", true, true);

https://bugs.chromium.org/p/chromium/issues/detail?id=721739发现


8

我遇到了相同的问题,本地服务器使用了自签名证书,以下是对我有效的组合:

ChromeOptions options = new ChromeOptions();
options.addArguments("--headless");
options.addArguments("--disable-gpu");
options.addArguments("--no-sandbox");
options.addArguments("--allow-insecure-localhost");

再澄清一点,UI服务器必须在Selenium测试运行的本地主机上运行,即https://localhost:443。 - singidunumx

6

试试这个:

final ChromeOptions options = new ChromeOptions();

options.addArguments("--headless");
options.addArguments("--window-size=1280,800");

WebDriver driver = new ChromeDriver(options);

@Gustave,你有可能解释一下为什么设置窗口大小会改变测试运行的方式吗?我还注意到,使用chromeoption --start-maximized启动无头浏览器会导致无头模式失败。虽然我不确定原因是什么。 - aseema31

2

对我来说,添加用户代理解决了这个问题:

--user-agent=Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36

1

options.add_argument("--window-size=1440, 900")

在尝试了其他人推荐的方法后,我从"Slyme"中找到了解决我的问题的方法。我的框架是Java。


1
目前你的回答不够清晰。请编辑并添加更多细节,以帮助其他人理解它如何回答所提出的问题。你可以在帮助中心找到有关如何撰写好答案的更多信息。 - Akzy

0

你的chromedriver/selenium组合看起来很完美。在我看来,这似乎是一个纯粹的同步问题。我们需要引入一些等待来进行同步,具体操作如下:

driver.get(url);
WebDriverWait wait = new WebDriverWait(driver, 10);
WebElement usernameTextfield = wait.until(ExpectedConditions.elementToBeClickable(driver.findElement(By.cssSelector(".input.username"))));
usernameTextfield.sendKeys("user_name");

0

我曾经遇到过完全相同的问题。

你需要在选项中添加你电脑的用户代理, 要搜索你的用户代理,只需在谷歌上输入:“我的用户代理

然后将其添加到选项中:options.add_argument("your-user-agent")


使用代理添加后出现以下错误:selenium.common.exceptions.WebDriverException: Message: 未知错误:Chrome启动失败:崩溃。 - Sergo055

0

对于那些可能因此错误而陷入困境,但使用Python的人。

当不使用无头浏览器时,我在脚本工作方面遇到了问题。

最初,我的选项看起来是这样的:

options = Options()
options.headless = True 

在找到这个线程后,我将我的选项更改为以下内容:
options = Options()
options.add_argument("--headless");
options.add_argument("--window-size=1440, 900")

当Selenium导航页面时,无头窗口的格式似乎不同。真是奇怪。这解决了我所有的问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接