• 异步网页采集利器CasperJs


    在采集网页中,我们会经常遇到采集一些异步加载页面的网页,我们通常用的httpwebrequest类就采集不到了,这个时候我们通常会采用webbrowser来辅助采集,但是.net下自带的webbrowser用起来非常不爽,在获取页面是否加载完毕的时候比较麻烦一些,DocumentCompleted事件遇到Iframe重复触发,而且获取到的源码通常也不是异步加载完之后的源码,往往我们需要加上定时器去不断的检查,才能获取到我们想要的源码。当然我们可以用一些第三方的webkit内核浏览器,但是这些判断页面是不是真正的加载完成也是比较费劲,而且体积都不小。

    今天就介绍一下CasperJSCasperJS是一个开源的导航脚本处理和测试工具,基于PhantomJS 和 slimerjs(前端自动化测试工具)编写。CasperJS简化了完整的导航场景的过程定义,提供了用于完成常见任务的实用的高级函数、方法和语法。CasperJS本身的功能很强大,内置了两种引擎PhantomJS 和 slimerjs 默认使用PhantomJS,具体详细的功能,大家可以参数这些官方网站去了解,或者加入QQ群389709524一块讨论,今天的重点讨论如何快速的采集到异步加载的网页。

    假如我们要采集dudu的这篇文章的评论 http://www.cnblogs.com/dudu/p/csharp-unicode-utf8.html,这篇文章查看源码是找不到这两条评论的,我们通过httpwebrequest也是获取不到的,这个时候我们通过casperjs就非常容易了。

    caperjs代码定义如下:

     1 var fs = require('fs');
     2 var casper = require('casper').create({
     3     pageSettings: {
     4         loadImages: false,
     5         loadPlugins: false
     6     },
     7     logLevel: "debug",//日志等级
     8     verbose: true,    // 记录日志到控制台
     9 });
    10 
    11 var url = casper.cli.raw.get('url');
    12 
    13 //请求页面
    14 casper.start(url, function () {
    15     fs.write("temp.html", this.getHTML(), 'w');
    16 });
    17 
    18 casper.run();

    结果如下:

    这样几行轻松的代码就获取到了异步加载的html代码了,是不是很简单,速度也是很快!

    当然在实际生产环境中这个还远远不够,我们要考虑各种网站的情景和各种网络状况,比如要考虑网络超时,一个网页一分钟加载不了我们就认为超时了,不然会一直等待,还有我们要过滤一下对于我们采集无关的请求,比较谷歌统计,百度统计,广告等,这个往往会拖慢网页的加载速度,另外页面的css样式,图片我们通常也不需要,都可以忽略,综上所述,我们的代码扩展成这样子。

      1 var fs = require('fs');
      2 
      3 var casper = require('casper').create({
      4     pageSettings: {
      5         loadImages: true,       
      6         loadPlugins: false,      
      7         userAgent: 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.137 Safari/537.36 LBBROWSER'
      8     },
      9     logLevel: "debug",//日志等级
     10     verbose: true,    // 记录日志到控制台
     11     timeout: 60000,//60秒超时,退出
     12 });
     13 
     14 
     15 var url = casper.cli.raw.get('url');
     16 
     17 //排除不相关的请求,加快页面加载进度
     18 casper.on('resource.requested', function(requestData, request) {    
     19     if (requestData.url.indexOf('google-analytics.com') > 0) {
     20         request.abort();
     21     }
     22     if (requestData.url.indexOf('googlesyndication.com') > 0) {
     23         request.abort();
     24     }
     25     if (requestData.url.indexOf('hm.baidu.com') > 0) {
     26         request.abort();
     27     }
     28     if (requestData.url.indexOf('baidustatic.com') > 0) {
     29         request.abort();
     30     }
     31     if (requestData.url.indexOf('share.baidu.com') > 0) {
     32         request.abort();
     33     }
     34     if (requestData.url.indexOf('cbjs.baidu.com') > 0) {
     35         request.abort();
     36     }
     37     if (requestData.url.indexOf('jiathis.com') > 0) {
     38         request.abort();
     39     }
     40     if (requestData.url.indexOf('.cnzz.com') > 0) {
     41         request.abort();
     42     }
     43     if (requestData.url.indexOf('.51.la') > 0) {
     44         request.abort();
     45     }
     46     if (requestData.url.indexOf('.tanx.com') > 0) {
     47         request.abort();
     48     }
     49     //this.echo("==============>page.resource.requested"+requestData.url);
     50 });
     51 
     52 //超时执行的函数,记录到日志文件
     53 casper.on('timeout', function () {
     54     //this.echo("===>timeout"+url);
     55     var fileName = this.evaluate(getFileName);
     56     var nowTime = this.evaluate(CurentTime);
     57     fs.write("log/timeout_" + fileName + ".txt", nowTime + "====>" + url + "
    ", 'a');
     58 });
     59 
     60 //请求页面
     61 casper.start(url, function () {
     62     var status = this.status().currentHTTPStatus;
     63     //this.capture('tt.png');
     64     fs.write("temp.html", this.getHTML(), 'w');
     65 });
     66 
     67 
     68 function getFileName() {
     69     var now = new Date();
     70 
     71     var year = now.getFullYear();       //
     72     var month = now.getMonth() + 1;     //
     73     var day = now.getDate();            //
     74 
     75     return (year + "" + month + "" + day);
     76 }
     77 
     78 function CurentTime() {
     79     var now = new Date();
     80 
     81     var year = now.getFullYear();       //
     82     var month = now.getMonth() + 1;     //
     83     var day = now.getDate();            //
     84 
     85     var hh = now.getHours();            //
     86     var mm = now.getMinutes();          //
     87 
     88     var clock = year + "-";
     89 
     90     if (month < 10)
     91         clock += "0";
     92 
     93     clock += month + "-";
     94 
     95     if (day < 10)
     96         clock += "0";
     97 
     98     clock += day + " ";
     99 
    100     if (hh < 10)
    101         clock += "0";
    102 
    103     clock += hh + ":";
    104     if (mm < 10) clock += '0';
    105     clock += mm;
    106     return (clock);
    107 }
    108 
    109 casper.run();
    View Code

    CasperJs的安装,可以参考官方网站的文档,或者关注下面的微信公众号 提供本文的所有工具和源码下载,本人也是最近刚接触,希望和大家一块讨论。今天写此文章还有个目的是,使用CasperJs的时候遇到一个页面个别文字出现乱码,一时找不到解决方案,欢迎知道的大侠帮忙指点下!情景如下:

    比如采集这个网页 http://meiri.jguo.cn/mryr/2014/1209/59249.html  这个网站编码是gb2312 采集的时候遇到 曹叡 的 “叡 ”会出现乱码,其他的文字没事,我自己测试了下,发现如果网站是utf-8编码的,采集的时候这个字没问题,但是咱们是采集程序,不可能要求别人改编码,所以目前还没有想到解决方案,还希望知道的同学,指点一二,在此谢了!

  • 相关阅读:
    Lab EIGRP不等价负载均衡
    Lab EIGRP metric计算
    EIGRP Troubleshooting Summary
    EIGRP Query Range查询过程详细分析
    EIGRP Auto-Summary Affect The Query Range
    EIGRP Distribute-list Affect The Query Range
    Understanding EIGRP Queries
    EIGRP DUAL
    33、为什么析构函数一般写成虚函数
    32、C和C++的类型安全
  • 原文地址:https://www.cnblogs.com/weiguang3100/p/4178343.html
Copyright © 2020-2023  润新知