zoukankan      html  css  js  c++  java
  • 浅谈网络爬虫爬js动态加载网页(二)

      没错,最后我还是使用了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,他是我需要的一个解决方案。

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

     1        File pathToBinary = new File("D:\Program Files (x86)\Mozilla Firefox\firefox.exe");
     2         FirefoxBinary ffBinary = new FirefoxBinary(pathToBinary);
     3         FirefoxProfile firefoxProfile = new FirefoxProfile();
     4         FirefoxDriver driver = new FirefoxDriver(ffBinary,firefoxProfile);
     5 
     6 
     7         driver.get("http://cq.qq.com/baoliao/detail.htm?294064");
     8 
     9         ArrayList list = new ArrayList();
    10         list.add("http://www.sina.com.cn");
    11         list.add("http://www.sohu.com");
    12         list.add("http://www.163.com");
    13         list.add("http://www.qq.com");
    14 
    15         long start,end;
    16 
    17         for(int i=0;i<list.size();i++){
    18             start = System.currentTimeMillis();
    19             driver.get(list.get(i).toString());
    20             end = System.currentTimeMillis();
    21             System.out.println(list.get(i).toString() + ":" + (end - start));
    22         }
    23 
    24         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等等,从而加速网页的速度,更关心其中的内容。

      简单方法如下:

    1 //去掉css        
      firefoxProfile.setPreference("permissions.default.stylesheet", 2);
    2 //去掉图片 3 firefoxProfile.setPreference("permissions.default.image", 2); 4 //去掉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

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

    常在博园走,也该湿湿鞋。
  • 相关阅读:
    前天去游泳了
    Microsoft今天开了中文的MSDN了,以后查资料有时要快了点吧
    Visual Studio .NET已检测到指定的WEB服务运行的不是ASP.NET 1.1版
    sqlserver 2005 利用游标解决标量值函数主键自增id批量导入数据问题
    nvarchar查询条件中不用加单引号''吗?
    使用标量值函数作为主键自增值的时候,动软代码生成器的插入方法需要去掉主键的参数。
    c#里的'0','1'对应sqlserver2005中的False,True
    三元运算符绑定缩略内容
    循环插入数据存储过程
    01|02|03| ====> (01,02,03)用于in id数组这种查询方式
  • 原文地址:https://www.cnblogs.com/yhdino/p/3263219.html
Copyright © 2011-2022 走看看