没错,最后我还是使用了Selenium,去实现上一篇我所说的问题,别的没有试,只试了一下firefox的引擎,总体效果对我来说还是可以接受的。

  继续昨天的话题,既然要实现上篇所说的问题,那么就需要一个可以执行js代码的框架。我首先选择的是htmlunit,先简单介绍一下htmlunit。下面一段摘自网络。

htmlunit 是一款开源的 java 页面分析工具,启动 htmlunit 之后,底层会启动一个无界面浏览器,用户可以指定浏览器类型:firefox、ie 等,如果不指定,默认采用 INTERNET_EXPLORER_7:
WebClient webClient = new WebClient(BrowserVersion.FIREFOX_3_6);

通过简单的调用:
HtmlPage page = webClient.getPage(url);
即可得到页面的 HtmlPage 表示,然后通过:
InputStream is = targetPage.getWebResponse().getContentAsStream()
即可得到页面的输入流,从而得到页面的源码,这对做网络爬虫的项目来说,很有用。
当然,也可以从 page 中得更多的页面元素。

很重要的一点是,HtmlUnit 提供对执行 javascript 的支持:
page.executeJavaScript(javascript)
执行 js 之后,返回一个 ScriptResult 对象,通过该对象可以拿到执行 js 之后的页面等信息。默认情况下,内部浏览器在执行 js 之后,将做页面跳转,跳转到执行 js 之后生成的新页面,如果执行 js 失败,将不执行页面跳转。

最后可以取得page.executeJavaScript(javascript).getNewPage(),获取执行后的页面。换句话说,javascript需要在这里人为的执行,显然与我的初衷不符,另外可能是我水平太差,在抓取sina新闻的页面时总是出错,暂时还没发现错误在何处,但按照网络上查询的结果来分析,极有可能错误的原因是在于htmlunit执行某些带参数的请求时,由于参数的顺序或者编码问题会导致请求失败而报错。关键是,运行后并没有得到我需要的结果。

  那么就另寻解决办法,这个时候就找到了Selenium WebDriver,他是我需要的一个解决方案。

  参考了资料和例子,就可以开始使用他了。实例代码如下。

        File pathToBinary = new File("D:\\Program Files (x86)\\Mozilla Firefox\\firefox.exe");
FirefoxBinary ffBinary = new FirefoxBinary(pathToBinary);
FirefoxProfile firefoxProfile = new FirefoxProfile();
FirefoxDriver driver = new FirefoxDriver(ffBinary,firefoxProfile); driver.get("http://cq.qq.com/baoliao/detail.htm?294064"); ArrayList list = new ArrayList();
list.add("http://www.sina.com.cn");
list.add("http://www.sohu.com");
list.add("http://www.163.com");
list.add("http://www.qq.com"); long start,end; for(int i=0;i<list.size();i++){
start = System.currentTimeMillis();
driver.get(list.get(i).toString());
end = System.currentTimeMillis();
System.out.println(list.get(i).toString() + ":" + (end - start));
} driver.close();

  使用了firefox的引擎,得到的结果如下,而且确实满足了我的要求。

  http://www.sina.com.cn:6638
  http://www.sohu.com:5796
  http://www.163.com:7567
  http://www.qq.com:9384

  可以看见如上的结果时间还是蛮长的,那如何加快速度呢。其实仔细考虑一下,为什么他要这么久,就是因为他在下载网页元素,我们请求一个网站的时候是发起一个req,得到一个res,而res中是只有元素没有内容的,换句话说,他不用执行css,js,不用下载图片,flash,加载广告等等。而如果我们需要加快效率,那就需要移除一切与我分析无关的东西,那么仿照浏览器一样,我们需要屏蔽掉css,图片,flash等等,从而加速网页的速度,更关心其中的内容。

  简单方法如下:

 //去掉css        
  firefoxProfile.setPreference("permissions.default.stylesheet", 2);
//去掉图片
firefoxProfile.setPreference("permissions.default.image", 2);
//去掉flash
  firefoxProfile.setPreference("dom.ipc.plugins.enabled.libflashplayer.so",false);

  那么在去除掉所有firefox缓存后,再次运行一下,会有什么结果呢。结果如下

  http://www.sina.com.cn:5085
  http://www.sohu.com:3520
  http://www.163.com:3329
  http://www.qq.com:2048

  发现确实快了很多。上面只是一个大致的原型,如果真正的要用,还需要封装。

浅谈网络爬虫爬js动态加载网页(二)的更多相关文章

  1. 浅谈网络爬虫爬js动态加载网页(一)

    由于别的项目组在做舆情的预言项目,我手头正好没有什么项目,突然心血来潮想研究一下爬虫.分析的简单原型.网上查查这方面的资料还真是多,眼睛都看花了.搜了搜对于我这种新手来说,想做一个简单的爬虫程序,所以 ...

  2. 浅谈网络爬虫爬js动态加载网页(三)

    上一篇讨论了web driver对动态网页的抓取与分析,可以很清楚的看出这是一种集中式处理方式,简单说,就是利用服务器,打开一个真正的brower,然后将需要解析的地址交给浏览器,浏览器去解析,然后将 ...

  3. 爬虫——爬取Ajax动态加载网页

    常见的反爬机制及处理方式 1.Headers反爬虫 :Cookie.Referer.User-Agent 解决方案: 通过F12获取headers,传给requests.get()方法 2.IP限制 ...

  4. 爬虫再探实战(四)———爬取动态加载页面——请求json

    还是上次的那个网站,就是它.现在尝试用另一种办法——直接请求json文件,来获取要抓取的信息. 第一步,检查元素,看图如下: 过滤出JS文件,并找出包含要抓取信息的js文件,之后就是构造request ...

  5. Scrapy 框架 使用 selenium 爬取动态加载内容

    使用 selenium 爬取动态加载内容 开启中间件 DOWNLOADER_MIDDLEWARES = { 'wangyiPro.middlewares.WangyiproDownloaderMidd ...

  6. Python+Selenium爬取动态加载页面(1)

    注: 最近有一小任务,需要收集水质和水雨信息,找了两个网站:国家地表水水质自动监测实时数据发布系统和全国水雨情网.由于这两个网站的数据都是动态加载出来的,所以我用了Selenium来完成我的数据获取. ...

  7. JS 动态加载脚本 执行回调

    JS 动态加载脚本  执行回调 关于在javascript里面加载其它的js文件的问题可能很多人都遇到过,但很多朋友可能并不知道怎么判断我们要加载的js文件是否加载完成,如果没有加载完成我们就调用文件 ...

  8. js动态加载以及确定加载完成的代码

    利用原生js动态加载js文件到页面,并在确定加载完成后调用相关function var otherJScipt = document.createElement("script") ...

  9. js动态加载css文件和js文件的方法

    今天研究了下js动态加载js文件和css文件的方法. 网上发现一个动态加载的方法.摘抄下来,方便自己以后使用 [code lang="html"] <html xmlns=& ...

随机推荐

  1. Javacript中(function(){})() 与 (function(){}()) 区别 {转}

    这个问题可以从不同的角度来看,但从结果上来说 :他们是一样的.首先,如果从AST(抽象语法树)的角度来看,两者的AST是一模一样的,最终结果都是一次函数调用.因此,就解析器产生的结果论而言,两者是没有 ...

  2. 游戏引擎网络开发者的 64 做与不做 | Part 1 | 客户端方面

    摘要:纵观过去 10 年的游戏领域,单机向网络发展已成为一个非常大的趋势.然而,为游戏添加网络支持的过程中往往存在着大量挑战,这里将为大家揭示游戏引擎网络开发者的 64 个做与不做. [编者按]时下, ...

  3. Linux性能检测命令 - vmstat

    一.vmstat命令描述 最常见的Linux/Unix监控工具想必是vmstat了,vmstat是Virtual Meomory Statistics(虚拟内存统计)的缩写,可以展现给定时间间隔的服务 ...

  4. SQL技术内幕-6 rank()over(order by XX COLLATE) 的用法

    DECLARE @Names TABLE ( name VARCHAR(20) ); INSERT INTO @Names VALUES ('DeSzmetch'),('DESZMETCH'),('D ...

  5. ubuntu下安装nodejs

    前言 继前几天在wins环境下使用cygwin模拟器安装nodejs出现了一些问题后,今天我决定在ubuntu下安装nodejs,安装过程非常顺利,没有报错,看来还是linux环境给力啊,由于刚接触l ...

  6. light oj 1205 - Palindromic Numbers 数位DP

    思路:搜索的时候是从高位到低位,所以一旦遇到非0数字,也就确定了数的长度,这样就知道回文串的中心点. 代码如下: #include<iostream> #include<cstdio ...

  7. mysql 连接数的最大数

    mysql默认最大连接数是100,增加加默认MYSQL连接数的方法有两个 方法一:进入MYSQL安装目录 打开MYSQL配置文件 my.ini(windows) 或 my.cnf(linux环境)查找 ...

  8. lintcode:格雷编码

    格雷编码 格雷编码是一个二进制数字系统,在该系统中,两个连续的数值仅有一个二进制的差异. 给定一个非负整数 n ,表示该代码中所有二进制的总数,请找出其格雷编码顺序.一个格雷编码顺序必须以 0 开始, ...

  9. 2016CVTE编程题:兔子藏洞

    兔子藏洞 题目描述 一只兔子藏身于20个圆形排列的洞中(洞从1开始编号),一只狼从x号洞开始找,下次隔一个洞找(及在x+2号洞找),在下次个两个洞找(及在x+5号洞找),以此类推...它找了n次仍然没 ...

  10. lintcode:线段树的修改

    线段树的修改 对于一棵 最大线段树, 每个节点包含一个额外的 max 属性,用于存储该节点所代表区间的最大值. 设计一个 modify 的方法,接受三个参数 root. index 和 value.该 ...