2

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())。

4

1 回答 1

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 客户端将连接到新的显示,而不是DISPLAY上下文生效之前的显示。

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

于 2014-11-29T12:18:54.897 回答