由Selenium启动的Firefox忽略由pyvirtualdisplay创建的显示 [英] Firefox started by Selenium ignores the display created by pyvirtualdisplay
问题描述
WebDriver
实例之前,我使用 pyvirtualdisplay
开始显示。如果我使用Chrome浏览器,则不会有任何问题:Chrome会显示在 pyvirtualdisplay
创建的Xephyr实例中。但是,当我使用Firefox时,会出现Xephyr实例,但Firefox显示在其外部。 下面是完全复制问题的代码:来自硒的
import webdriver
from selenium.webdriver.firefox.webdriver import FirefoxBinary
import pyvirtualdisplay
$ b binary = FirefoxBinary()
with pyvirtualdisplay.Display(visible = True):
if True:#设置为False以使用Chrome ...
驱动程序= webdriver.Firefox(无,二进制)
其他:
驱动程序= webdriver.Chrome( )
driver.get(http://www.google.com)
driver.quit()
上面的代码是一个更复杂的代码的最小版本(这解释了看起来没有用处的 FirefoxBinary()
)。 移动你创建的 FirefoxBinary
由 pyvirtualdisplay.Display
>来自selenium的从selen导入webdriver
ium.webdriver.firefox.webdriver导入FirefoxBinary
导入pyvirtualdisplay
$ b与pyvirtualdisplay.Display(可见= True):
如果True:#设置为False使用Chrome ...
binary = FirefoxBinary()
driver = webdriver.Firefox(None,binary)
else:
driver = webdriver.Chrome()
驱动程序。 get(http://www.google.com)
driver.quit()
< h3>说明
问题出在幕后。名为 DISPLAY
的环境变量决定了Firefox和Chrome连接的位置。这不是你想要设置的方式。
以下是你的代码:
-
创建一个
FirefoxBinary
的实例。如果你阅读了源代码,你将会看到,当这个类的一个对象被创建的时候,它会复制os.environ
(环境)您可以使用pyvirtualdisplay.Display
创建一个显示,并将其用作上下文管理器。当你进入上下文时,显示会改变os.environ
,所以只要上下文有效,DISPLAY
设置环境变量,以便X客户端连接到新的显示器,而不是在上下文生效之前DISPLAY
是。 > -
您创建您的驱动程序。当您使用Chrome时,一切正常,因为Chrome会从修改的环境中获取
DISPLAY
变量。但是,当您使用Firefox时,它将使用第一步中复制的环境中的DISPLAY
环境。此环境包含值显示
之前的步骤中所描述的变更,因此它不会连接到您创建的新显示。
I start a display with pyvirtualdisplay
before creating my WebDriver
instance. If I use Chrome, it works without any problem: Chrome shows up in the Xephyr instance that pyvirtualdisplay
creates. However, when I use Firefox, the Xephyr instance appears but Firefox shows up outside of it.
Here is code that fully reproduces the problem:
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()
The code above is a minimal version of code that is more complex (which explains the seemingly useless FirefoxBinary()
).
Solution
Move your creation of the FirefoxBinary
object inside the context managed by 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()
Explanation
The problem is what happens behind the scenes. The environment variable named DISPLAY
is what determines where Firefox and Chrome will connect to. It is not set in the way you'd expect it to be set.
Here is what happens with your code:
You create an instance of
FirefoxBinary
. If you read the source code, you'll see that when an object of this class is created it makes a copy ofos.environ
(the environment).You create a display with
pyvirtualdisplay.Display
and use it as a context manager. As you enter the context, the display altersos.environ
so that as long as the context is in effect, theDISPLAY
environment variable is set so that X clients will connect to the new display instead of whatDISPLAY
was before the context came into effect.You create your driver. When you use Chrome, everything is fine because Chrome will get its
DISPLAY
variable from the modified environment. However, when you use Firefox, it will use theDISPLAY
environment from the environment that was copied in the first step. This environment contains a value ofDISPLAY
which is prior to the alteration described in the previous step, so it does not connect to the new display you created.
这篇关于由Selenium启动的Firefox忽略由pyvirtualdisplay创建的显示的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!