一尘不染

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

selenium

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


阅读 297

收藏
2020-06-26

共1个答案

一尘不染

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之前 在上一步骤中所描述的变化,所以它不会连接到您创建的新的显示。

2020-06-26