使用Selenium來抓取動態加載的頁面

有些頁面是經過js以及ajax動態加載的,例如:花瓣網。這時若是咱們直接分析原始頁面的html,是得不到有效的信息的。固然,由於不管怎樣動態加載,基礎信息總歸是包含在初始頁面中得,因此咱們能夠用爬蟲代碼來模擬js代碼,js讀取頁面元素值,咱們也讀取頁面元素值;js發送ajax,咱們就拼湊參數、發送ajax並解析返回的json。這樣總歸是能作的,可是比較麻煩,有沒有比較省力的方法呢?比較好的方法大概是內嵌一個瀏覽器了。
   Selenium 是一個模擬瀏覽器,進行自動化測試的工具,它提供一組API能夠與真實的瀏覽器內核交互。Selenium是跨語言的,有 Java 、C#、python等版本,而且支持多種瀏覽器,chrome、firefox以及IE都支持。
  在Java項目中使用Selenium,須要作兩件事:
  在項目中引入Selenium的Java模塊,以Maven爲例:
  <dependency> <groupId>org.seleniumhq.selenium</groupId> <artifactId>selenium-java</artifactId> <version>2.33.0</version> </dependency>
  下載對應的driver,以chrome爲例: http://code.google.com/p/chromedriver/downloads/list
  下載後,須要將driver的位置寫到Java的環境變量裏,例如我在mac下將其下載到了/Users/yihua/Downloads/chromedriver,則須要在程序裏添加如下代碼(固然在JVM參數裏寫-Dxxx=xxx也是能夠的):
  System.getProperties().setProperty("webdriver.chrome.driver","/Users/yihua/Downloads/chromedriver");
  Selenium的API挺簡單的,核心是WebDriver,下面是動態渲染頁面,並獲取最終html的代碼:
@Test
public void testSelenium() {
System.getProperties().setProperty("webdriver.chrome.driver", "/Users/yihua/Downloads/chromedriver");
WebDriver webDriver = new ChromeDriver();
webDriver.get(" http://huaban.com/ ");
WebElement webElement = webDriver.findElement(By.xpath("/html"));
System.out.println(webElement.getAttribute("outerHTML"));
webDriver.close();
}
  值得注意的是,每次new ChromeDriver(),Selenium都會創建一個Chrome進程,並使用一個隨機端口在Java中與chrome進程進行通訊來交互。因而可知有兩個問題:
  所以若是直接關閉Java程序,Chrome進程多是沒法關閉的。這裏須要顯示的調用webDriver.close()來關閉進程。
  建立進程的開銷仍是比較大的,儘可能對webDriver進行復用會比較好。惋惜根據官方的文檔,webDriver不是線程安全的,因此咱們須要創建一個webDriver池來保存它們。不清楚Selenium是否有這樣的接口,反正我是本身寫了一個WebDriverPool來完成這個任務。
相關文章
相關標籤/搜索