linux 環境下 Java 執行 selenium 無介面 chrome 環境設定
前言
ofollow,noindex">《Java 中使用 selenium 和 chrome 瀏覽器下載動態網頁》 一文中,演示瞭如何在 window 環境下通過 selenium 和 chrome 來下載動態網頁。但是我們的爬蟲一般是執行在 linux 伺服器上的。伺服器上一般是沒有 GUI 環境的。無法開啟 chrome 視窗介面。以前的時候,爬蟲系統是用一種無介面的瀏覽器 PhantomJS 來實現。但是現在因為 FireFox 、chrome 這些瀏覽器開始支援無頭模式後, PhantomJS 已經停止更新了。所謂的無頭模式就是無介面執行模式,正好適合在 linux 伺服器這種沒有 GUI 環境的情況下使用。
在 linux 環境下使用 selenium 驅動 chrome 需要安裝 chrome 瀏覽器和 chrome webdriver。下面在 centos 7 環境下展示應該如何做。
安裝 google chrome
首先從地址 https://dl.google.com/linux/direct/google-chrome-stable_current_x86_64.rpm 下載離線安裝包。然後執行下面的命令安裝 chrome 需要的依賴包
yum install libX11 libXcursor libXdamage libXext libXcomposite libXi libXrandr gtk3 libappindicator-gtk3 xdg-utils libXScrnSaver liberation-fonts
然後執行命令安裝 chrome
rpm -ivh google-chrome-stable_current_x86_64.rpm
完成後執行下面的命令檢視版本
[root@localhost ~]# google-chrome --version Google Chrome 70.0.3538.110
可以看出當前版本為 70 版本
安裝 chrome webdriver
和文章 《Java 中使用 selenium 和 chrome 瀏覽器下載動態網頁》 中一樣,找到支援 70 版本 chrome 的下載地址,下載 linux 平臺版本的檔案 chromedriver_linux64.zip 即可

web driver 不同平臺
無頭模式 selenium chrome 呼叫程式樣例
還是以 《Java 中使用 selenium 和 chrome 瀏覽器下載動態網頁》 中的程式為基礎,將他改造為無頭模式
WebDriver webDriver = null; try { String url = "https://www.jianshu.com/p/675ea919230e"; ChromeOptions chromeOptions=new ChromeOptions(); //設定 chrome 的無頭模式 chromeOptions.setHeadless(Boolean.TRUE); //啟動一個 chrome 例項 webDriver = new ChromeDriver(chromeOptions); //訪問網址 webDriver.get(url); Document document = Jsoup.parse(webDriver.getPageSource()); Element titleElement = document.selectFirst("div.article h1.title"); Element authorElement = document.selectFirst("div.article div.author span.name"); Element timeElement = document.selectFirst("div.article span.publish-time"); Element wordCountElement = document.selectFirst("div.article span.wordage"); Element viewCountElement = document.selectFirst("div.article span.views-count"); Element commentCountElement = document.selectFirst("div.article span.comments-count"); Element likeCountElement = document.selectFirst("div.article span.likes-count"); Element contentElement = document.selectFirst("div.article div.show-content"); if (titleElement != null) { System.out.println("標題:" + titleElement.text()); } if (authorElement != null) { System.out.println("作者:" + authorElement.text()); } if (timeElement != null) { System.out.println("釋出時間:" + timeElement.text()); } if (wordCountElement != null) { System.out.println(wordCountElement.text()); } if (viewCountElement != null) { System.out.println(viewCountElement.text()); } if (commentCountElement != null) { System.out.println(commentCountElement.text()); } if (likeCountElement != null) { System.out.println(likeCountElement.text()); } if (contentElement != null && contentElement.text() != null) { System.out.println("正文長度:" + contentElement.text().length()); } } catch (Exception e) { e.printStackTrace(); } finally { if (webDriver != null) { //退出 chrome webDriver.quit(); } }
和前文中的程式碼相比,就是下面的地方不一樣
ChromeOptions chromeOptions=new ChromeOptions(); //設定 chrome 的無頭模式 chromeOptions.setHeadless(Boolean.TRUE); //啟動一個 chrome 例項 webDriver = new ChromeDriver(chromeOptions);
這個引數決定了是否用無頭模式來啟動
將程式打包並且上傳到 linux 伺服器上,執行命令
java -jar -Dwebdriver.chrome.driver=/data/deploy/chromedriver spider_demo-0.0.1-SNAPSHOT.jar
控制檯會打印出下面的內容
標題:是什麼支撐了淘寶雙十一,沒錯就是它java程式語言。 作者:Java幫幫 釋出時間:2018.08.29 14:49 字數 561 閱讀 632 評論 0 喜歡 4 正文長度:655
說明在 linux 用 java 通過 selenium 呼叫 chrome 訪問這個網頁成功了。如果沒有設定上面的無頭模式引數,那麼執行的時候將會出現下面的提示
org.openqa.selenium.WebDriverException: unknown error: Chrome failed to start: exited abnormally (unknown error: DevToolsActivePort file doesn't exist) (The process started from chrome location /usr/bin/google-chrome is no longer running, so ChromeDriver is assuming that Chrome has crashed.) (Driver info: chromedriver=2.44.609551 (5d576e9a44fe4c5b6a07e568f1ebc753f1214634),platform=Linux 3.10.0-514.26.2.el7.x86_64 x86_64) (WARNING: The server did not provide any stacktrace information) Command duration or timeout: 399 milliseconds Build info: version: 'unknown', revision: 'unknown', time: 'unknown' System info: host: 'iz2ze9kvzy03hms75m3jzlz', ip: '172.17.251.3', os.name: 'Linux', os.arch: 'amd64', os.version: '3.10.0-514.26.2.el7.x86_64', java.version: '1.8.0_171' Driver info: driver.version: ChromeDriver at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) at java.lang.reflect.Constructor.newInstance(Constructor.java:423) at org.openqa.selenium.remote.ErrorHandler.createThrowable(ErrorHandler.java:214) at org.openqa.selenium.remote.ErrorHandler.throwIfResponseFailed(ErrorHandler.java:166) at org.openqa.selenium.remote.JsonWireProtocolResponse.lambda$new$0(JsonWireProtocolResponse.java:53) at org.openqa.selenium.remote.JsonWireProtocolResponse.lambda$getResponseFunction$2(JsonWireProtocolResponse.java:91) at org.openqa.selenium.remote.ProtocolHandshake.lambda$createSession$0(ProtocolHandshake.java:122) at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193) at java.util.Spliterators$ArraySpliterator.tryAdvance(Spliterators.java:958) at java.util.stream.ReferencePipeline.forEachWithCancel(ReferencePipeline.java:126) at java.util.stream.AbstractPipeline.copyIntoWithCancel(AbstractPipeline.java:498) at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:485) at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471) at java.util.stream.FindOps$FindOp.evaluateSequential(FindOps.java:152) at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) at java.util.stream.ReferencePipeline.findFirst(ReferencePipeline.java:464) at org.openqa.selenium.remote.ProtocolHandshake.createSession(ProtocolHandshake.java:125) at org.openqa.selenium.remote.ProtocolHandshake.createSession(ProtocolHandshake.java:73) at org.openqa.selenium.remote.HttpCommandExecutor.execute(HttpCommandExecutor.java:136) at org.openqa.selenium.remote.service.DriverCommandExecutor.execute(DriverCommandExecutor.java:83) at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:548) at org.openqa.selenium.remote.RemoteWebDriver.startSession(RemoteWebDriver.java:212) at org.openqa.selenium.remote.RemoteWebDriver.<init>(RemoteWebDriver.java:130) at org.openqa.selenium.chrome.ChromeDriver.<init>(ChromeDriver.java:181) at org.openqa.selenium.chrome.ChromeDriver.<init>(ChromeDriver.java:168) at org.openqa.selenium.chrome.ChromeDriver.<init>(ChromeDriver.java:123) at com.yanggaochao.spider.SpiderDemoApplication.run(SpiderDemoApplication.java:34) at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:813) at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:797) at org.springframework.boot.SpringApplication.run(SpringApplication.java:324) at org.springframework.boot.SpringApplication.run(SpringApplication.java:1260) at org.springframework.boot.SpringApplication.run(SpringApplication.java:1248) at com.yanggaochao.spider.SpiderDemoApplication.main(SpiderDemoApplication.java:21) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:48) at org.springframework.boot.loader.Launcher.launch(Launcher.java:87) at org.springframework.boot.loader.Launcher.launch(Launcher.java:50) at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:51)
這樣,我們就可以在我們的爬蟲系統裡面採用瀏覽器的方式下載網頁,實現所見即所得的下載效果。再也不用擔心動態渲染的網頁內容無法下載了。