2)JS动态生成HTML元素的爬取

import java.util.List;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;

import cn.edu.hfut.dmic.webcollector.crawler.DeepCrawler;
import cn.edu.hfut.dmic.webcollector.model.Links;
import cn.edu.hfut.dmic.webcollector.model.Page;

/*
 * JS爬取
 * Refer: http://blog.csdn.net/smilings/article/details/7395509
 */
public class WebCollector3 extends DeepCrawler {

	public WebCollector3(String crawlPath) {
		super(crawlPath);
		// TODO Auto-generated constructor stub
	}

	@Override
	public Links visitAndGetNextLinks(Page page) {
		/*HtmlUnitDriver可以抽取JS生成的数据*/
//		HtmlUnitDriver driver=PageUtils.getDriver(page,BrowserVersion.CHROME);
//		String content = PageUtils.getPhantomJSDriver(page);
        WebDriver driver = PageUtils.getWebDriver(page);
//        List<WebElement> divInfos=driver.findElementsByCssSelector("#feed_content");
        List<WebElement> divInfos=driver.findElements(By.cssSelector("#feed_content span"));
        for(WebElement divInfo:divInfos){
            System.out.println("Text是:" + divInfo.getText());
        }
        return null;
	}

	public static void main(String[] args) {
		WebCollector3 crawler=new WebCollector3("/home/hu/data/wb");
        for(int page=1;page<=5;page++)
//        crawler.addSeed("http://www.sogou.com/web?query="+URLEncoder.encode("编程")+"&page="+page);
        crawler.addSeed("http://cq.qq.com/baoliao/detail.htm?294064");
        try {
			crawler.start(1);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

}

PageUtils.java

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.htmlunit.HtmlUnitDriver;
import org.openqa.selenium.ie.InternetExplorerDriver;
import org.openqa.selenium.phantomjs.PhantomJSDriver;

import com.gargoylesoftware.htmlunit.BrowserVersion;

import cn.edu.hfut.dmic.webcollector.model.Page;

public class PageUtils {
	public static HtmlUnitDriver getDriver(Page page) {
        HtmlUnitDriver driver = new HtmlUnitDriver();
        driver.setJavascriptEnabled(true);
        driver.get(page.getUrl());
        return driver;
    }

    public static HtmlUnitDriver getDriver(Page page, BrowserVersion browserVersion) {
        HtmlUnitDriver driver = new HtmlUnitDriver(browserVersion);
        driver.setJavascriptEnabled(true);
        driver.get(page.getUrl());
    	return driver;
    }

    public static WebDriver getWebDriver(Page page) {
//    	WebDriver driver = new HtmlUnitDriver(true);

//    	System.setProperty("webdriver.chrome.driver", "D:\\Installs\\Develop\\crawling\\chromedriver.exe");
//    	WebDriver driver = new ChromeDriver();

    	System.setProperty("phantomjs.binary.path", "D:\\Installs\\Develop\\crawling\\phantomjs-2.0.0-windows\\bin\\phantomjs.exe");
    	WebDriver driver = new PhantomJSDriver();
    	driver.get(page.getUrl());

//    	JavascriptExecutor js = (JavascriptExecutor) driver;
//    	js.executeScript("function(){}");
    	return driver;
    }

    public static String getPhantomJSDriver(Page page) {
    	Runtime rt = Runtime.getRuntime();
    	Process process = null;
    	try {
			process = rt.exec("D:\\Installs\\Develop\\crawling\\phantomjs-2.0.0-windows\\bin\\phantomjs.exe " +
			"D:\\workspace\\crawlTest1\\src\\crawlTest1\\parser.js " +
			page.getUrl().trim());
			InputStream in = process.getInputStream();
			InputStreamReader reader = new InputStreamReader(
					in, "UTF-8");
			BufferedReader br = new BufferedReader(reader);
			StringBuffer sbf = new StringBuffer();
			String tmp = "";
			while((tmp = br.readLine())!=null){
                sbf.append(tmp);
            }
			return sbf.toString();
		} catch (IOException e) {
			e.printStackTrace();
		}

    	return null;
    }
}

2.1)HtmlUnitDriver getDriver是selenium 1.x的作法,已经outdate了,现在用WebDriver getWebDriver

2.2)这里用了几种方法:HtmlUnitDriver, ChromeDriver, PhantomJSDriver,
PhantomJS,参考 http://blog.csdn.net/five3/article/details/19085303,各自之间的优缺
点如下:

driver类型 优点 缺点 应用
真实浏览器driver 真实模拟用户行为 效率、稳定性低 兼容性测试
HtmlUnit 速度快 js引擎不是主流的浏览器支持的 包含少量js的页面测试
PhantomJS 速度中等、模拟行为接近真实 不能模拟不同/特定浏览器的行为 非GUI的功能性测试

* 真实浏览器driver 包括 Firefox, Chrome, IE

2.3)用PhantomJSDriver的时候,遇上错
误:ClassNotFoundException: org.openqa.selenium.browserlaunchers.Proxies,原
因竟然是selenium 2.44 的bug,后来通过maven找到phantomjsdriver-1.2.1.jar 才解决了。

2.4)另外,我还试了PhantomJS 原生调用(也就是不用selenium,直接调用PhantomJS,见上面的方法),原生要调用JS,这里的parser.js代码如下:

system = require('system')
address = system.args[1];//获得命令行第二个参数 接下来会用到
//console.log('Loading a web page');
var page = require('webpage').create();
var url = address;
//console.log(url);
page.open(url, function (status) {
    //Page is loaded!
    if (status !== 'success') {
        console.log('Unable to post!');
    } else {
    //此处的打印,是将结果一流的形式output到java中,java通过InputStream可以获取该输出内容
        console.log(page.content);
    }
    phantom.exit();
});

3)后话

3.1)HtmlUnitDriver + PhantomJSDriver是当前最可靠的动态抓取方案。

3.2)这过程中用到很多包、exe,遇到很多的墙~,有需要的朋友可以找我要。

Reference

http://www.ibm.com/developerworks/cn/web/1309_fengyq_seleniumvswebdriver/
http://blog.csdn.net/smilings/article/details/7395509
http://phantomjs.org/download.html
http://blog.csdn.net/five3/article/details/19085303
http://phantomjs.org/quick-start.html

... ...

动态网页爬取例子(WebCollector+selenium+phantomjs)

2)JS动态生成HTML元素的爬取的更多相关文章

  1. JS动态生成的元素,其对应的方法不响应(比如单击事件,鼠标移动事件等)

    主要原因:在页面给元素注册点击事件的时候[ $(function () {  XXX }); ],JS动态生成的元素还尚未生成,所以click事件就没有生效 解决方法: 方案一:js动态生成元素后再给 ...

  2. Javascript动态生成的页面信息爬取和openpyxl包FAQ小记

    最近,笔者在使用Requests模拟浏览器发送Post请求时,发现程序返回的html与浏览器F12观察到的略有不同,经过观察返回的response.text,cookies确认有效,因为我们可以看到返 ...

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

    代码也可以从我的开源项目HtmlExtractor中获取. 当我们在进行数据抓取的时候,如果目标网站是以Js的方式动态生成数据且以滚动页面的方式进行分页,那么我们该如何抓取呢? 如类似今日头条这样的网 ...

  4. js 动态生成html 触发事件传参字符转义

    通常,在使用 JS 动态生成 html 的过程中,会嵌入相应的样式.事件等属性元素,而这时经常会出现所谓的 “单.双引号不够用” 的情况,别急,这时可以利用 html 语言中的转义字符来解决.下面就来 ...

  5. 爬虫案例(js动态生成数据)

    需求:爬取https://www.xuexi.cn/f997e76a890b0e5a053c57b19f468436/018d244441062d8916dd472a4c6a0a0b.html页面中的 ...

  6. 动态生成html元素并为元素追加属性

    动态生成HTML元素的方法有三种: 第一种:document.createElement()创建元素,再用appendChild( )方法将元素添加到指定节点 <!DOCTYPE html> ...

  7. 抓取js动态生成的数据分析案例

    需求:爬取https://www.xuexi.cn/f997e76a890b0e5a053c57b19f468436/018d244441062d8916dd472a4c6a0a0b.html页面中的 ...

  8. Angular如何给动态生成的元素绑定事件

    在AngularJS中,操作DOM一般在指令中完成,事件监听机制是在对于已经静态生成的dom绑定事件,而如果在指令中动态生成了DOM节点,动态生成的节点不会被JS事件监听. 举例来说: angular ...

  9. js动态生成canvas

    最近看代码发现一个小现象,就是用js动态生成的canvas在浏览器审查元素的时候,发现它没有结束标签,但是不会影响canvas上图形的绘制,同时还有一点就是在动态设置canvas宽度和高度的时候,不要 ...

随机推荐

  1. Swift - 给表格UITableView添加索引功能(快速定位)

    像iOS中的通讯录,通过点击联系人表格右侧的字母索引,我们可以快速定位到以该字母为首字母的联系人分组.   要实现索引,我们只需要两步操作: (1)实现索引数据源代理方法 (2)响应点击索引触发的代理 ...

  2. MTD中的nand驱动初步分析---面向u-boot

    之前提到nand驱动的初始化分析,有一个结构体 struct mtd_info始终贯穿这些代码 再来分析一下这个结构体的基本功能,如何初始化,如何使用 一.分析过程 看看结构体的出现和使用方式 第一次 ...

  3. c/c++ 动态申请数组

    new和delete运算符用于动态分配和撤销内存的运算符 new使用方法: 1.     开辟单变量地址空间 1)new int;  //开辟一个存放数组的存储空间,返回一个指向该存储空间的地址.in ...

  4. POJ 1273 Drainage Ditches(网络流,最大流)

    Description Every time it rains on Farmer John's fields, a pond forms over Bessie's favorite clover ...

  5. matlab中plot使用方法

    MATLAB有非常强的图形功能,能够方便地实现数据的视觉化.强大的计算功能与图形功能相结合为MATLAB在科学技术和教学方面的应用提供了更加广阔的天地.以下着重介绍二维图形的画法,对三维图形仅仅作简单 ...

  6. 免费APP在线測试工具以及其用法

    免费APP漏洞安全检測工具:http://safe.ijiami.cn/ 漏洞分析是爱加密推出免费 APP 漏洞分析平台,服务包含一键对APK 进行签名数据信息採集.内部配置信息採集.市场渠道相关信息 ...

  7. 【Dev Club 分享】腾讯验证码的十二年

    源:http://mp.weixin.qq.com/s?__biz=MzA3NTYzODYzMg==&mid=2653578147&idx=3&sn=94a8f8f8b4a23 ...

  8. 根据图像路径,创建CBitmap对象的方法

    因为项目的关系,需要根据图像路径,创建CBitmap对象.起初查资料找到了LoadBitmap这个函数,根据CSDN得 BOOL LoadBitmap ( LPCTSTR lpszResourceNa ...

  9. 简单概率dp(期望)-zoj-3640-Help Me Escape

    题目链接: http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=4808 题目大意: 有n条路,选每条路的概率相等,初始能力值为f,每 ...

  10. 如何在Android Studio上使用Github

    首先,登陆到Github上并创建一个新repository.在屏幕右上角,点击“+”标记,并且选择“New repository”. 现在完成这个表格以新建一个叫做testproject的新repos ...