Linux服務器上使用Chrome Headless

Headless簡介

Headless Chrome來了,你現在可以在headless/server環境中運行瀏覽器了。什麼?讓瀏覽器運行在沒有界面的服務器端環境中,那瀏覽器可以用來幹嘛。

想象一下每次在發版前,測試人員都需要測試系統的功能,重複且乏味。於是你決定讓程序自動測試界面上的功能。你不需要瀏覽器有GUI界面,想通過編程的方法來驅動瀏覽器進行各種操作,並且希望能在服務器端運行,這樣每次發版前就可以自動測試相關功能,提高測試效率。

在Ubuntu/Linux服務器上使用Chrome Headless

以上只是一個應用場景,Headless瀏覽器可以理解為沒有GUI界面的瀏覽器程序。由於沒有界面,所以在速度上比普通瀏覽器稍快,它可以在自動化測試、性能檢查、獲取元數據(例如爬蟲)和網頁截圖等方面發揮用途。

對比

在Chrome瀏覽器還沒有原生支持Headless之前,早期瀏覽器可以通過Xvfb服務處理圖形顯示從而實現Headless模式,近期火狐也在積極研發原生支持Headless模式,預計在Firefox 56版本中實現。還有一種方案是通過封裝瀏覽器內核來實現Headless。比較知名的比如PhantomJS(目前僅維護)封裝了QtWebKit內核,SlimerJS封裝了Gecko內核,TrifleJS封裝了IE內核。

而使用這些框架的時候,可能會出現很多奇怪的問題。這些程序是運行在封閉環境中的,所以會導致和外部通信很繁瑣,並且由於採用的內核比較老,從而很多新特性,新語法不支持,並非真實的用戶環境。所以提倡用Headless模式替代這些框架,從而獲得更好的效果。

DevTools協議

Chrome DevTools是一套可以用來和Chrome瀏覽器通信的協議,平常我們開發調試Chrome程序用的開發者工具即是基於該協議實現的一個網頁程序。Chrome開發者工具通過Socket和Chrome進行通信,瀏覽器中的一個Tab頁面即對應一個Socket通道。然後互相進行數據交換,從而實現對網頁的檢查、調試和監控等功能。

我們可以用命令行參數在客戶端來遠程調試頁面。在命令行中加入參數“—remote-debuggingport=9222”啟動Chrome後,在瀏覽器進入“localhost:9222”即可看到調試界面。其中我們可以通過網絡面板中的WebSocket連接來查看調試程序和Chrome進行的數據收發。我們可以把該協議當成瀏覽器的API,想實現什麼功能,需要發送固定格式的信息過去,瀏覽器接收後會返回相應的數據。

Headless應用

在自動化測試和網絡爬蟲等領域會經常用到該項新特性。

1、自動化測試

自動化測試有許多的框架,比較好用的比如Nightmare,這是一款基於Electron的自動化測試庫,語法漂亮好用。最近這個庫也計劃從Electron遷移到Headless Chrome。我們也可以結合Karma來實現UI的自動化測試,這樣可以保證代碼在真實環境中運行。

2、網絡爬蟲

網絡爬蟲應用在以前的方案中,會有較多問題,比如數據抓取不全。現在很多的網站都做成了單頁應用,採用AJAX交互,傳統爬蟲能拿到的數據有限,如果不執行前端代碼,就拿不到有用的信息。此時,我們可以用Headless Chrome來執行相關的代碼,將頁面執行完成後,在對相應的頁面進行分析。這比其他方案能有更好的穩定性,不過由於目前這方面的庫還不是很成熟,導致需要自己去寫一些底層的實現,在開發效率上會比較慢。

3、自動截圖

自動截圖也可以被應用到Headless中。在前端代碼報錯後,如果希望能把當前錯誤頁面的截圖併發給監控程序,目前的純前端做法可以採用html2canvas。但用過這個庫後,你會發現有的截圖效果很不理想,和原來的界面差距較大。那可以換個角度,採用後端截圖的方法。由於頁面展示本質是HTML和CSS。我們可以在服務器端部署Chrome Headless服務器,裡面加載對應網站的資源,等前端報錯後,只需將前端整個頁面的Dom數據發送給服務器,服務器把相應內容的Dom替換後,由於CSS一般是提取出來的,所以客戶端和服務端樣式表一致,Dom結構一致,數據一致,即可以將服務器端截圖併發送給監控程序。

4、實戰預渲染

Prerender和Server-side render(SSR) 兩種技術都是解決首屏渲染問題,以此來提高用戶體驗的方案。Prerender方案不需要後端是Node.js。其實本質上,Prerender只提供一個假的靜態首頁預先給客戶看到樣式,不具備應用的功能。

在目前的SPA網站中,首屏大多會有一個id為app的元素。等框架資源加載完成後,框架會動態替換app元素為真正的應用樣子。而在資源尤其是打包後的JavaScript文件沒加載完成之前,頁面基本處於白屏的狀態。而Prerender正是希望用一個固定的樣式來代替這個白屏的狀態。

目前實現預渲染的簡單方案可以採用幾張圖片,來給用戶直觀的應用佈局樣式,從而增加用戶等待的時長。複雜一點可以採用webpack將預先寫好的樣式組件打包後內聯寫入首屏頁面,包括寫入JavaScript腳本,寫入HTML和CSS等。讓用戶可以快速瞭解應用的名字,整體顏色佈局信息。具體做成什麼樣,需要由應用本身來決定。但不希望在首頁中有過多的內嵌代碼,否則拖慢初始加載速度導致後續資源加載變慢的話,預渲染效果也會不理想。

我們可以用Headless來實現預渲染,有兩種預渲染方案。

一種是在服務器端,當請求過來後,把請求動態掛在Headless Chrome裡,然後把Chrome裡面的Dom拿到後返回給客戶端,這個也可以做成SPA應用程序通用的SEO優化方案。

另一種是在代碼發佈階段將靜態樣式內嵌寫入網站首頁。在打包階段開啟靜態服務器,然後用Headless Chrome來訪問對應的網站,並得到網站的Dom。和骨架圖不同的是,這時候的Dom應該是網站真實渲染後的Dom。

在實際應用中,會碰到渲染出頁面結構含有開發時髒數據問題。如果把開發時的數據去掉,會影響整體頁面的佈局,因為有的佈局是靠內容撐起來的。所以我們採用了字符替換的方法,把文字數據替換為&nbsp,這樣既保留了佔位,又去掉了髒數據。對於圖片的處理需要把圖片的href更換為默認URL圖片,有的icon如果是內聯數據,需要去掉。總之一個原則,讓頁面初始加載骨架看起來和真實結構一致。可以採用在編碼的時候,在元素的屬性上設置標誌符,來表明文字或者圖片是否需要被替換。處理完後,需要有效果,其前提是把CSS文件在打包的時候單獨提取出來,這樣在初始加載時才會有效果。然後通過webpack打包把處理後的Dom數據內嵌到首頁中。當用戶首次訪問的時候,首頁就已內嵌有了對應的Dom結構,讓用戶對網站佈局有個大概的感知,減少用戶等待時間。

幾個月前發佈的Chrome59beta推出了headless模式。原生的Chrome,更好的通用性,更快的速度……似乎是時候和Phantomjs、Ghost們說再見了。搜索一圈發現大多數人都是在桌面版的linux或者mac上嚐了鮮,然而要將Chrome用於web2.0爬蟲的的話,還是得在服務器版的linux中運行。安裝chrome測試環境:Ubuntu14.04如果是桌面版的ubuntu,直接到官網下載最新版chrome安裝就好。對於服務器版的ubuntu,需要用命令行安裝:

一、Ubuntu 14.04版本安裝

1、安裝

sudo apt-get install libxss1 libappindicator1 libindicator7

wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb

sudo dpkg -i google-chrome-stable_current_amd64.deb

sudo apt-get install -f

2、安裝完成後我們使用下面命令測試下:

google-chrome --headless --remote-debugging-port=9222 https://chromium.org --disable-gpu

可能出現沒有權限運行錯誤,解決方法如下:(沒有可以忽略)

在Ubuntu/Linux服務器上使用Chrome Headless

1.找到google-chrome文件(一般默認安裝路徑基本都在這個地方)

我的位置位於/opt/google/chrome/

2.用gedit打開google-chrome文件

找到 exec -a "$0" "$HERE/chrome" "$@" ,可以執行搜索命令

3.在後面添加 –user-data-dir –no-sandbox即可,整條shell命令就是

exec -a "$0" "$HERE/chrome" "$@" --user-data-dir --no-sandbox

4.再重新打開google-chrome即可正常訪問!

3、再次執行第二步命令:可能會出現下面問題,如圖:

在Ubuntu/Linux服務器上使用Chrome Headless

解決方式:

<code>sudo apt install --reinstall libnss3 /<code>

4、再次運行第2步驟命令:啟動成功,如圖

在Ubuntu/Linux服務器上使用Chrome Headless

5、這裡是使用headless模式進行遠程調試,ubuntu上大多沒有gpu,所以–disable-gpu 以免報錯。之後使用另一個命令行訪問本地的9222端口:

curl http://localhost:9222

能夠看到調試信息應該就是裝好了。

二、在CentOS7中安裝Google Chrome(補充)

1、首先進入根目錄,然後進入etc/yum.repos.d目錄下,創建google-chrome.repo文件;

2、在文件中添加以下內容-> ESC 退出到命令模式,shift+q , x保存退出。

<code>[google-chrome] /<code>

<code>name=google-chrome /<code>

<code>baseurl=http://dl.google.com/linux/chrome/rpm/stable/$basearch /<code>

<code>enabled=1/<code>

<code>gpgcheck=1 /<code>

<code>gpgkey=https://dl-ssl.google.com/linux/linux_signing_key.pub/<code>

3、加入谷歌源保存後,執行下面命令

yum -y install google-chrome-stable --nogpgcheck

在終端中,我們還可以做以下操作:

獲取屏幕截圖:

google-chrome --headless --disable-gpu --screenshot --window-size=1280,1696 http://www.leepeng.com.cn

獲取頁面為PDF:

google-chrome --headless --disable-gpu --print-to-pdf http://www.leepeng.com.cn

打印頁面DOM:

google-chrome --headless --disable-gpu --dump-dom http://www.leepeng.com.cn


分享到:


相關文章: