起因
近期在做一个对某网站进行数据抓取,因为数据无法直接通过接口获得,只能通过浏览器请求并登陆获取,所以采用了Selenium2,也就是Webdriver进行模拟用户行为。开发阶段在我的MacOS中执行都没有问题,但是生产环境是没有用户界面的CentOS,所以花费了一天时间来解决这个问题。
解决方案
- Webdriver 3.3.1
- Firefox 37
- Xvfb
步骤
1.引用WebDriver
因为我是在Java中调用Webdriver进行模拟行为,所以第一步就是写好对应的代码,在maven或者gradle中引入webdriver的依赖,例如:
#pom.xml
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>3.3.1</version>
</dependency>```
对应的逻辑代码网上有很多,例如:
```WebDriver driver = newFirefoxDriver();```
这一部分对WebDriver的操作我就不多说了,网上很多教程,可以根据自己的实际逻辑进行编写。
######2. 安装Firefox 37
我采用的是WebDriver3.3.1版本,通过多次调试使用FireFox52的时候,浏览器无法正常执行代码指令,后来换成47版本,但是依然有一些小问题,后来尝试了37版本,顺利执行。所以这里我将服务器上的Firefox换成了37版本。对于其他版本能否正常执行,有体力的朋友可以测试后给出反馈。
在[Firefox all version](https://ftp.mozilla.org/pub/firefox/releases/)中可以下载到所有版本的firefox,可以下载到本地后通过scp命令上传到服务器。
执行解压对应名字的压缩包
tar xvf firefox-37.0.tar.bz2
如果CentOS7.0可能会出现如下错误:
tar -jxvf target_gile.tar.bz2
tar (child): bzip2: Cannot exec: No such file or directory
tar (child): Error is not recoverable: exiting now
tar: Child returned status 2
tar: Error is not recoverable: exiting now
这时候只需要安装bzip2
yum install bzip2
tar -jxvf firefox-37.0.tar.bz2
解压出错:[参考1](http://stackoverflow.com/questions/26958741/extract-tar-the-tar-bz2-file-error)
接下来用我们下载的旧版本替换系统已存在或者不存在的firefox
备份之前的firefox
mv /usr/bin/firefox /usr/bin/firefox-backup
创建firefox命令与你解压得到文件夹中firefox文件的关联
ln -s pathToFirefox/firefox /usr/bin/firefox
查看版本
firefox -version
如果看到相应版本的输出说明我们执行的没有问题。
相关参考:[参考1](http://linoxide.com/ubuntu-how-to/install-firefox-37-ubuntu-centos-fedora/),[参考2](http://xmodulo.com/how-to-install-old-firefox-on-linux.html)
######3. 安装Xvfb
这一步才是这次调试最重要的部分,因为Centos是没有用户界面的,所以我们不能通过正常的执行流程打开Firefox进行模拟行为或者测试。
执行步骤:
yum -y install firefox Xvfb libXfont Xorg
yum -y groupinstall "X Window System" "Desktop" "Fonts" "General Purpose Desktop"
Launch an XWindows Virtual Frame Buffer(XVFB) session on display port 99
Xvfb :99 -ac -screen 0 1280x1024x24 &
Tell all XWindows applications in this terminal session to use the new Xvfb display port
export DISPLAY=:99
这样我们就在99端口齐了一个Xvfb的窗口,这个窗口是渲染在内存中,这一步可以参考:[Set up and run Selenium on CentOS](http://chandrewz.github.io/blog/selenium-on-centos)
接下来我们就要在我们的逻辑代码中指定Firefox在相应的端口启动:
public static void main(String[] args) throws IOException {
// Setup firefox binary to start in Xvfb
String Xport = System.getProperty("lmportal.xvfb.id", ":1");
final File firefoxPath = new File(System.getProperty(
"lmportal.deploy.firefox.path", "/usr/bin/firefox"));
FirefoxBinary firefoxBinary = new FirefoxBinary(firefoxPath);
firefoxBinary.setEnvironmentProperty("DISPLAY", Xport);
// Start Firefox driver
WebDriver driver = new FirefoxDriver(firefoxBinary, null);
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
driver.get("http://google.com/");
// Take snapshot of browser
File srcFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
FileUtils.copyFile(srcFile, new File("ffsnapshot.png"));
driver.quit();
}
到这里我们就可以在服务器上执行我们的项目跑一下看能否成功了。
参考:[Headless tests with Firefox WebDriver](http://www.seleniumtests.com/2012/04/headless-tests-with-firefox-webdriver.html)
#总结
通过这个项目说明了在没有用户界面进行Webdriver的模拟用户行为是可取的,建议在开发阶段现在本地调试好,对于服务器没有用户界面的时如果有和预期不同的结果时,我们可以调用截图的方法保存图像,然后再后续查看进行调试。
#补充
后来已经通过在MAC上登陆后,获取到cookie,然后在服务器登上通过Selenium登陆时候绕过登陆的方法。
[selenium WebDriver对cookie进行处理绕过登录验证码](http://www.51testing.com/html/41/15116141-3711141.html)
driver.manage().deleteAllCookies()
Cookie loginCookie = new Cookie(cookieKey, cookieValue, "/")
driver.manage().addCookie(loginCookie)```