起因
近期在做一個對某網站進行數據抓取,因為數據無法直接通過接口獲得,只能通過瀏覽器請求并登陸獲取,所以采用了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)```