pyvirtualdisplay在创建WebDriver实例之前,我先从中进行显示。如果我使用的是Chrome,它可以正常工作:Chrome会显示在pyvirtualdisplay创建的Xephyr实例中。但是,当我使用Firefox时,会出现Xephyr实例,但Firefox会显示在其外部。
pyvirtualdisplay
WebDriver
这是完全重现该问题的代码:
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()
将FirefoxBinary对象的创建移动到由pyvirtualdisplay.Display以下内容管理的上下文中:
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的连接位置。它的设置方式与您期望的设置方式不同。
DISPLAY
这是您的代码发生的情况:
您创建的实例FirefoxBinary。如果您阅读源代码,将会看到在创建此类的对象时, 它会复制os.environ(环境)。
os.environ
您可以pyvirtualdisplay.Display使用创建一个显示并将其用作上下文管理器。当你进入的背景下,显示器会改变os.environ,这样只要上下文中的效果,DISPLAY环境变量被设置成X客户端将连接到新的显示,而不是什么DISPLAY是 之前 的背景下生效。
您创建您的驱动程序。使用Chrome时,一切都很好,因为Chrome将从DISPLAY修改后的环境中获取其变量。但是,当您使用Firefox时,它将使用 第一步中复制 的DISPLAY环境 中的环境。 这个环境包括一个值DISPLAY是 之前 在上一步骤中所描述的变化,所以它不会连接到您创建的新的显示。