前言
《Java 中使用 selenium 和 chrome 瀏覽器下載動態(tài)網(wǎng)頁》 一文中,演示了如何在 window 環(huán)境下通過 selenium 和 chrome 來下載動態(tài)網(wǎng)頁。但是我們的爬蟲一般是運行在 linux 服務(wù)器上的。服務(wù)器上一般是沒有 GUI 環(huán)境的。無法打開 chrome 窗口界面。以前的時候,爬蟲系統(tǒng)是用一種無界面的瀏覽器 PhantomJS 來實現(xiàn)。但是現(xiàn)在因為 FireFox 、chrome 這些瀏覽器開始支持無頭模式后, PhantomJS 已經(jīng)停止更新了,所以現(xiàn)在推薦使用 FireFox 和 chrome 的無頭模式來替代 PhantomJS 了。所謂的無頭模式就是無界面運行模式,正好適合在 linux 服務(wù)器這種沒有 GUI 環(huán)境的情況下使用。
在 linux 環(huán)境下使用 selenium 驅(qū)動 chrome 需要安裝 chrome 瀏覽器和 chrome webdriver。下面在 centos 7 環(huán)境下展示應(yīng)該如何做。
安裝 google chrome
首先從地址 https://dl.google.com/linux/direct/google-chrome-stable_current_x86_64.rpm 下載離線安裝包。然后執(zhí)行下面的命令安裝 chrome 需要的依賴包
yum install libX11 libXcursor libXdamage libXext libXcomposite libXi libXrandr gtk3 libappindicator-gtk3 xdg-utils libXScrnSaver liberation-fonts
然后執(zhí)行命令安裝 chrome
rpm -ivh google-chrome-stable_current_x86_64.rpm
完成后執(zhí)行下面的命令查看版本
[root@localhost ~]# google-chrome --version
Google Chrome 70.0.3538.110
可以看出當前版本為 70 版本
安裝 chrome webdriver
和文章 《Java 中使用 selenium 和 chrome 瀏覽器下載動態(tài)網(wǎng)頁》 中一樣,找到支持 70 版本 chrome 的下載地址,下載 linux 平臺版本的文件 chromedriver_linux64.zip 即可
無頭模式 selenium chrome 調(diào)用程序樣例
還是以 《Java 中使用 selenium 和 chrome 瀏覽器下載動態(tài)網(wǎng)頁》 中的程序為基礎(chǔ),將他改造為無頭模式
WebDriver webDriver = null;
try {
String url = "http://www.lxweimin.com/p/675ea919230e";
ChromeOptions chromeOptions=new ChromeOptions();
//設(shè)置 chrome 的無頭模式
chromeOptions.setHeadless(Boolean.TRUE);
//啟動一個 chrome 實例
webDriver = new ChromeDriver(chromeOptions);
//訪問網(wǎng)址
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("發(fā)布時間:" + 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();
//設(shè)置 chrome 的無頭模式
chromeOptions.setHeadless(Boolean.TRUE);
//啟動一個 chrome 實例
webDriver = new ChromeDriver(chromeOptions);
這個參數(shù)決定了是否用無頭模式來啟動
將程序打包并且上傳到 linux 服務(wù)器上,執(zhí)行命令
java -jar -Dwebdriver.chrome.driver=/data/deploy/chromedriver spider_demo-0.0.1-SNAPSHOT.jar
控制臺會打印出下面的內(nèi)容
標題:是什么支撐了淘寶雙十一,沒錯就是它java編程語言。
作者:Java幫幫
發(fā)布時間:2018.08.29 14:49
字數(shù) 561
閱讀 632
評論 0
喜歡 4
正文長度:655
說明在 linux 用 java 通過 selenium 調(diào)用 chrome 訪問這個網(wǎng)頁成功了。如果沒有設(shè)置上面的無頭模式參數(shù),那么執(zhí)行的時候?qū)霈F(xiàn)下面的提示
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)
這樣,我們就可以在我們的爬蟲系統(tǒng)里面采用瀏覽器的方式下載網(wǎng)頁,實現(xiàn)所見即所得的下載效果。再也不用擔心動態(tài)渲染的網(wǎng)頁內(nèi)容無法下載了。