转载

抓取Js动态生成数据且以滚动页面方式分页的网页

当我们在进行数据抓取的时候,如果目标网站是以Js的方式动态生成数据且以滚动页面的方式进行分页,那么我们该如何抓取呢?

如类似今日头条这样的网站: http://toutiao.com/

我们可以使用 Selenium 来搞定这件事情。Selenium的设计目的虽然是用于Web应用程序的自动化测试,但是却非常适合用来做数据抓取,可以非常简单地绕过网站的反爬虫限制,因为Selenium直接运行在浏览器中,就像真正的用户在操作一样。

使用Selenium,我们不但可以抓取Js动态生成数据的网页,而且可以抓取以滚动页面方式分页的网页。

首先,我们使用maven引入Selenium依赖:

Xml代码   抓取Js动态生成数据且以滚动页面方式分页的网页
  1. <dependency>  
  2.     <groupId>org.seleniumhq.selenium</groupId>  
  3.     <artifactId>selenium-java</artifactId>  
  4.     <version>2.47.1</version>  
  5. </dependency>  

接下来就可以写代码抓取了:

Java代码   抓取Js动态生成数据且以滚动页面方式分页的网页
  1. import org.openqa.selenium.By;  
  2. import org.openqa.selenium.WebDriver;  
  3. import org.openqa.selenium.WebElement;  
  4. import org.openqa.selenium.firefox.FirefoxDriver;  
  5.   
  6. import java.util.List;  
  7. import java.util.Random;  
  8.   
  9. /** 
  10.  * 如何抓取Js动态生成数据且以滚动页面方式分页的网页 
  11.  * 以抓取今日头条为例说明:http://toutiao.com/ 
  12.  * Created by ysc on 10/13/15. 
  13.  */  
  14. public class Toutiao {  
  15.     public static void main(String[] args) throws Exception{  
  16.   
  17.         //等待数据加载的时间  
  18.         //为了防止服务器封锁,这里的时间要模拟人的行为,随机且不能太短  
  19.         long waitLoadBaseTime = 3000;  
  20.         int waitLoadRandomTime = 3000;  
  21.         Random random = new Random(System.currentTimeMillis());  
  22.   
  23.         //火狐浏览器  
  24.         WebDriver driver = new FirefoxDriver();  
  25.         //要抓取的网页  
  26.         driver.get("http://toutiao.com/");  
  27.   
  28.         //等待页面动态加载完毕  
  29.         Thread.sleep(waitLoadBaseTime+random.nextInt(waitLoadRandomTime));  
  30.   
  31.         //要加载多少页数据  
  32.         int pages=5;  
  33.         for(int i=0; i<pages; i++) {  
  34.             //滚动加载下一页  
  35.             driver.findElement(By.className("loadmore")).click();  
  36.             //等待页面动态加载完毕  
  37.             Thread.sleep(waitLoadBaseTime+random.nextInt(waitLoadRandomTime));  
  38.         }  
  39.   
  40.         //输出内容  
  41.         //找到标题元素  
  42.         List<WebElement> elements = driver.findElements(By.className("title"));  
  43.         int j=1;  
  44.         for(int i=0;i<elements.size();i++) {  
  45.             try {  
  46.                 WebElement element = elements.get(i).findElement(By.tagName("a"));  
  47.                 //输出标题  
  48.                 System.out.println((j++) + "、" + element.getText() + " " + element.getAttribute("href"));  
  49.             }catch (Exception e){  
  50.                 System.out.println("ignore "+elements.get(i).getText()+" because "+e.getMessage());  
  51.             }  
  52.         }  
  53.   
  54.         //关闭浏览器  
  55.         driver.close();  
  56.     }  
  57. }  

代码也可以从我的开源项目 HtmlExtractor 中获取。

这里我们共抓取了6页,每页20条新闻,共120条新闻, 代码运行结果 。

本文转自:http://my.oschina.net/apdplat/blog/516848

正文到此结束
Loading...