由Selenium启动的Firefox忽略了pyvirtualdisplay创建的显示

时间:2014-11-29 12:18:55

标签: python firefox selenium pyvirtualdisplay

在创建pyvirtualdisplay实例之前,我使用WebDriver启动显示。如果我使用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())。

1 个答案:

答案 0 :(得分:8)

解决方案

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的连接位置。它没有按照您期望的方式设置。

以下是您的代码:

  1. 您创建了FirefoxBinary的实例。如果您阅读了源代码,您会看到当创建此类的对象时它会复制os.environ(环境)

  2. 使用pyvirtualdisplay.Display创建显示并将其用作上下文管理器。当您输入上下文时,显示会更改os.environ,以便只要上下文生效,就会设置DISPLAY环境变量,以便X客户端将连接到新显示而不是{{1} 在上下文生效之前<}>

  3. 您创建了驱动程序。当您使用Chrome时,一切都很好,因为Chrome会从修改后的环境中获取其DISPLAY变量。但是,当您使用Firefox时,它将使用第一步中复制的环境中的DISPLAY环境此环境包含DISPLAY的值先前到上一步骤中描述的更改,因此它不会连接到您创建的新显示。