一般咱們使用Java提供的HttpURLConnection或者Apache的HttpClient獲取的網頁源代碼都是直觀可見的,其代碼的內容和經過瀏覽器右鍵網頁->點擊查看網頁源代碼的內容一致。html
可是如今愈來愈多的網站使用Js來動態生成內容來提升相應速度,而HttpClient只是返回後端相應的response的請求主體,並無返回瀏覽器生成的網頁,因此對於Js生成的內容HttpClient是獲取不了的。java
對於獲取Js生成的網頁,咱們主要經過模擬瀏覽器的運行,渲染response的請求主體最終獲得對應的內容,獲得的內容和經過瀏覽器右鍵網頁->點擊檢查/查看元素的內容一致。web
咱們這裏講的模擬方法大概有兩種:windows
咱們此次的目標是獲取bilibili動態生成的動畫列表,左上是抓取的目標列表,左下是瀏覽器渲染的html內容,右面是服務器返回的response的正文。經過對比,咱們能夠看出目標列表是Js生成。
後端
Selenium是一個用於Web應用自動化測試的工具,更多的介紹就谷歌。這裏咱們主要用做模擬頁面的運行並將結果返回,對於網頁截圖的功能也是可行的。瀏覽器
Selenium支持模擬不少瀏覽器,可是咱們這裏只模擬PhantomJS,由於PhantomJS 是一個腳本化的無界面 WebKit,以 JavaScript 爲腳本語言實現各項功能。因爲是無界面的,因此速度性能方面會較好。服務器
1.下載
使用PhantomJS須要到官網下載最新的客戶端,這裏使用phantomjs-2.1.1-windows.zipmaven
2.maven依賴引入:ide
<dependency> <groupId>org.seleniumhq.selenium</groupId> <artifactId>selenium-java</artifactId> <version>2.53.0</version> </dependency> <dependency> <groupId>com.codeborne</groupId> <artifactId>phantomjsdriver</artifactId> <version>1.2.1</version> <exclusions> <exclusion> <groupId>org.seleniumhq.selenium</groupId> <artifactId>selenium-remote-driver</artifactId> </exclusion> <exclusion> <groupId>org.seleniumhq.selenium</groupId> <artifactId>selenium-java</artifactId> </exclusion> </exclusions> </dependency>
3.示例代碼工具
import org.openqa.selenium.WebDriver; import org.openqa.selenium.phantomjs.PhantomJSDriver; import org.openqa.selenium.phantomjs.PhantomJSDriverService; import org.openqa.selenium.remote.DesiredCapabilities; import java.util.ArrayList; /** * @author GinPonson */ public class TestSelenium { static final String HOST = "127.0.0.1"; static final String PORT = "80"; static final String USER = "gin"; static final String PWD = "12345"; public static void main(String[] args){ System.setProperty("phantomjs.binary.path", "D:\\phantomjs-2.1.1-windows\\bin\\phantomjs.exe"); DesiredCapabilities capabilities = DesiredCapabilities.phantomjs(); //設置代理或者其餘參數 ArrayList<String> cliArgsCap = new ArrayList<>(); //cliArgsCap.add("--proxy=http://"+HOST+":"+PORT); //cliArgsCap.add("--proxy-auth=" + USER + ":" + PWD); //cliArgsCap.add("--proxy-type=http"); capabilities.setCapability(PhantomJSDriverService.PHANTOMJS_CLI_ARGS, cliArgsCap); //capabilities.setCapability("phantomjs.page.settings.userAgent", ""); WebDriver driver = new PhantomJSDriver(capabilities); driver.get("http://www.bilibili.com/video/bangumi-two-1.html"); System.out.println(driver.getPageSource()); driver.quit(); } }
4.其餘功能
HtmlUnit功能上算是是Selenium的一個子集,Selenium有對應的HtmlUnit實現。HtmlUnit是用Java寫的無界面的瀏覽器,正由於其沒有界面,所以執行的速度仍是能夠的。
1.maven依賴引入
<dependency> <groupId>net.sourceforge.htmlunit</groupId> <artifactId>htmlunit</artifactId> <version>2.25</version> </dependency>
2.Java代碼
/** * @author GinPonson */ public class TestHtmlUnit { static final String HOST = "127.0.0.1"; static final String PORT = "80"; static final String USER = "gin"; static final String PWD = "12345"; public static void main(String[] args) throws Exception{ WebClient webClient = new WebClient(); //設置代理 //ProxyConfig proxyConfig = webClient.getOptions().getProxyConfig(); //proxyConfig.setProxyHost(HOST); //proxyConfig.setProxyPort(Integer.valueOf(PORT)); //DefaultCredentialsProvider credentialsProvider = (DefaultCredentialsProvider) webClient.getCredentialsProvider(); //credentialsProvider.addCredentials(USER, PWD); //設置參數 //webClient.getOptions().setCssEnabled(false); //webClient.getOptions().setJavaScriptEnabled(false); webClient.getOptions().setThrowExceptionOnScriptError(false); HtmlPage page = webClient.getPage("http://www.bilibili.com/video/bangumi-two-1.html"); System.out.println(page.asXml()); webClient.close(); } }
3.其餘功能
PhantomJS和HtmlUnit模擬瀏覽器頁面的生成功能都不錯,PhantomJS做爲一個無界面的WebKit,渲染頁面的功能很是完善,並且帶有瀏覽器截圖功能,能模擬登陸操做。HtmlUnit使用Rhino引擎來解析Js,有時候解析速度很是慢,就像上面的例子,費了很長時間,可是HtmlUnit能夠獲取頁面,解析元素一套作完(固然解析元素仍是使用Jsoup好),是不錯的工具。
HtmlUnit遇到錯誤後,先後處理相差7分鐘,多是我不會用QAQ
歡迎補充:)