如何在Xvfb中运行Selenium?

100

我在EC2实例上。因此没有图形界面。

$pip install selenium
$sudo apt-get install firefox xvfb

然后我执行这个操作:

$Xvfb :1 -screen 0 1024x768x24 2>&1 >/dev/null &

$DISPLAY=:1 java -jar selenium-server-standalone-2.0b3.jar
05:08:31.227 INFO - Java: Sun Microsystems Inc. 19.0-b09
05:08:31.229 INFO - OS: Linux 2.6.32-305-ec2 i386
05:08:31.233 INFO - v2.0 [b3], with Core v2.0 [b3]
05:08:32.121 INFO - RemoteWebDriver instances should connect to: http://127.0.0.1:4444/wd/hub
05:08:32.122 INFO - Version Jetty/5.1.x
05:08:32.123 INFO - Started HttpContext[/selenium-server/driver,/selenium-server/driver]
05:08:32.124 INFO - Started HttpContext[/selenium-server,/selenium-server]
05:08:32.124 INFO - Started HttpContext[/,/]
05:08:32.291 INFO - Started org.openqa.jetty.jetty.servlet.ServletHandler@1186fab
05:08:32.292 INFO - Started HttpContext[/wd,/wd]
05:08:32.295 INFO - Started SocketListener on 0.0.0.0:4444
05:08:32.295 INFO - Started org.openqa.jetty.jetty.Server@1ffb8dc

好的,现在一切都应该正常工作了,对吧?

当我运行我的代码时:

from selenium import webdriver
from selenium.common.exceptions import NoSuchElementException
from selenium.webdriver.common.keys import Keys

browser = webdriver.Firefox() 
browser.get("http://www.yahoo.com") 

我得到了这个:

Error: cannot open display: :0

4
如果你在没有运行X的系统上,display :0应该是可用的。尝试运行Xvfb:0--也可以查看@ema提到的xvfb-run。 - fijiaaron
1
对于未来的关注者,我在Ubuntu Server上描述了我的解决方案:https://www.namekdev.net/2016/08/selenium-server-without-x-window-system-xvfb/ - Namek
6个回答

183

你可以使用PyVirtualDisplay(Xvfb的Python包装器)来运行无头的WebDriver测试。

#!/usr/bin/env python

from pyvirtualdisplay import Display
from selenium import webdriver

display = Display(visible=0, size=(800, 600))
display.start()

# now Firefox will run in a virtual display. 
# you will not see the browser.
browser = webdriver.Firefox()
browser.get('http://www.google.com')
print browser.title
browser.quit()

display.stop()

更多信息


你也可以使用xvfbwrapper,这是一个类似的模块(但没有外部依赖项):

from xvfbwrapper import Xvfb

vdisplay = Xvfb()
vdisplay.start()

# launch stuff inside virtual display here

vdisplay.stop()

或者更好地,将其用作上下文管理器:

from xvfbwrapper import Xvfb

with Xvfb() as xvfb:
    # launch stuff inside virtual display here.
    # It starts/stops in this code block.

2
@Andrei OSX默认不使用X11。 - sam boosalis
使用此答案使其在OS X上与vagrant + PyCharm + Django一起工作:http://stackoverflow.com/q/29343109 - chachan
当我实现上面的pyvirtualdisplay代码时,我会收到“浏览器似乎已退出”的错误提示。 - gtownrower

46

最简单的方法可能是使用xvfb-run:

DISPLAY=:1 xvfb-run java -jar selenium-server-standalone-2.0b3.jar

xvfb-run会为您完成整个X权限过程,请尝试使用它!


这正是我一直在寻找的。仅仅启动Xvfb并不能为我解决问题,但使用xvfb-run却成功了。谢谢。 - Rey Abolofia
10
“DISPLAY=:1”是不必要的;xvfb-run会在启动指定命令(在您的情况下为“java -jar selenium-server…”)之前将DISPLAY环境变量设置为其他内容(通常为“:99”)。 - Alex Dupuy

37

打开终端并运行此命令:xhost +。这个命令需要在每次重启机器后再次运行。如果一切正常,您可以将此命令添加到启动命令中。

另外,请确保在您的 /etc/environment 文件中有以下一行:

export DISPLAY=:0.0 

然后运行你的测试来查看问题是否解决。

请在使用此方法前注意下面 sardathrion 的评论。


你只需要在命令行中执行 java -jar selenium-server-standalone-2.0b3.jar,然后运行你的测试。 - A.J
我正在使用EC2实例,因此没有GUI界面。xhost: 无法打开显示“:0.0”。 - TIMEX
@owa 在客户端环境中还需要DISPLAY环境变量。 - Keith
10
xhost + 不安全,请勿使用。如果你必须使用 xhost,只添加特定的机器而不是 + (即所有机器)。 - Sardathrion - against SE abuse

22

这是我使用的设置:

在运行测试之前,请执行:

export DISPLAY=:99
/etc/init.d/xvfb start

在测试之后:

/etc/init.d/xvfb stop

我使用的 init.d 文件看起来像这样:

#!/bin/bash
XVFB=/usr/bin/Xvfb XVFBARGS="$DISPLAY -ac -screen 0 1024x768x16" PIDFILE=${HOME}/xvfb_${DISPLAY:1}.pid case "$1" in start) echo -n "正在启动虚拟 X frame 缓冲区:Xvfb" /sbin/start-stop-daemon --start --quiet --pidfile $PIDFILE --make-pidfile --background --exec $XVFB -- $XVFBARGS echo "。" ;; stop) echo -n "正在停止虚拟 X frame 缓冲区:Xvfb" /sbin/start-stop-daemon --stop --quiet --pidfile $PIDFILE echo "。" ;; restart) $0 stop $0 start ;; *) echo "用法:/etc/init.d/xvfb {start|stop|restart}" exit 1 esac exit 0

我按照这个步骤做了,然后运行了我的脚本。但是,我仍然遇到了这个错误:无法打开显示器::0。另外,我需要运行Selenium Java服务器吗?似乎无论我是否运行它都没有关系... - TIMEX
2
如果您使用WebDriver,那么您就不需要Selenium Java服务器。 - Corey Goldberg

4
如果你使用Maven,可以使用xvfb-maven-plugin在测试之前启动Xvfb,使用相关的DISPLAY环境变量运行它们,并在所有测试结束后停止Xvfb。参考链接:xvfb-maven-plugin

2

正确的方法是:

xvfb-run python ./selenium-script.py

不需要添加:
from pyvirtualdisplay import Display
display = Display(visible=0, size=(800, 600))
display.start()
display.stop()

但是现在,有了Selenium WebDriver,就不再需要运行xvfb了(请参阅解释)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接