我在创建WebDriver
实例之前用pyvirtualdisplay
启动显示。如果我使用Chrome,它可以正常工作:Chrome显示在pyvirtualdisplay
创建的Xephyr实例中。但是,当我使用 Firefox 时,Xephyr 实例会出现,但 Firefox 会显示在它之外。
以下是完全重现该问题的代码:
from selenium import webdriver
from selenium.webdriver.firefox.webdriver import FirefoxBinary
import pyvirtualdisplay
binary = FirefoxBinary()
with pyvirtualdisplay.Display(visible=True):
if True: # Set to False to use Chrome...
driver = webdriver.Firefox(None, binary)
else:
driver = webdriver.Chrome()
driver.get("http://www.google.com")
driver.quit()
上面的代码是更复杂的代码的最小版本(这解释了看似无用的FirefoxBinary()
(。
解决方案
将FirefoxBinary
对象的创建移动到由 pyvirtualdisplay.Display
管理的上下文中:
from selenium import webdriver
from selenium.webdriver.firefox.webdriver import FirefoxBinary
import pyvirtualdisplay
with pyvirtualdisplay.Display(visible=True):
if True: # Set to False to use Chrome...
binary = FirefoxBinary()
driver = webdriver.Firefox(None, binary)
else:
driver = webdriver.Chrome()
driver.get("http://www.google.com")
driver.quit()
解释
问题是幕后发生了什么。名为 DISPLAY
的环境变量决定了 Firefox 和 Chrome 将连接到的位置。它不是按照您希望的方式设置
以下是代码发生的情况:
创建
FirefoxBinary
的实例。如果您阅读源代码,您将看到当创建此类的对象时,它会复制os.environ
(环境(。您可以使用
pyvirtualdisplay.Display
创建显示,并将其用作上下文管理器。当您输入上下文时,显示会更改os.environ
以便只要上下文有效,就会设置DISPLAY
环境变量,以便 X 客户端将连接到新显示,而不是上下文生效之前DISPLAY
。创建驱动程序。当您使用Chrome时,一切都很好,因为Chrome将从修改后的环境中获取其
DISPLAY
变量。但是,当您使用 Firefox 时,它将使用第一步中复制的环境中的DISPLAY
环境。此环境包含上一步中所述更改之前的值DISPLAY
,因此它不会连接到您创建的新显示器。