原理: 用 XMLHTTP 定期(10分钟一次)访问BLOG、帖子等等,发现内容长度变长了,就发出提醒。
技术注意:因为 XMLHTTP 不能跨站进行访问的,但是本地Html文件却可以访问任意域名,因而,程序运行在一个内嵌IE的VC++编写的窗口中,而且还是访问本地页面,在此页面执行js就可以访问任意域名了。{
 name:'blog demon',
 global_name:'',//全局名,有装入器填写
 desc:'回帖盯哨机器人,程序员专用IM百宝箱',
 browser:null,
 db:null,
 UrlList:null,
 checkOutTimer:null,
 currentGetBodyIndex:-1,
 init:function(this_){
  if(this_.db==null){
   this_.db=new dobject("SQLite3Wrapper");
   var fn=System.GetDataPath()+"blog_demon.db3";
   this_.db.open(fn);
   this_.db.query("create table blogs(url varchar(250),html text,html_len int,status int)");
  }
  this_.UrlList=new Array();
  if(this_.db.query("select * from blogs")){
   while(this_.db.fetch()){
    var url=this_.db.get_array_data("url");
    this_.UrlList.push(url);
   }
  }
  this_.checkOutTimer=setInterval(this_.global_name+".OnTimer("+this_.global_name+")",5*60000);//5分钟检查一次
 },
 setup:function(this_){
  if(this_.browser==null){
   this_.browser=new dobject("MiniBrowser",1);
   this_.browser.OnNavigateComplete2=new Function("",this_.global_name+".setHTML("+this_.global_name+");");
  }    var w=730;
  var h=410;
  this_.browser.SetPosition(-9999,-9999,w,h);
  
  blog_demon_OnUrlListOk=function(obj_global_name,urls){eval("var obj="+obj_global_name);obj.OnUrlListOk(obj,urls);};  this_.browser.OnHttpClientRead=function(socket_text,method,RequestFileName,params,ContentType,ContentLength,PostContent){
   var urls="";
   for(var i=0;i<this_.UrlList.length;i++){
    urls+=this_.UrlList[i]+"\n";
   }   var body="<body style='background:#ABC7F7'>";
   body+="输入需要盯哨的博文URL,本程序将以每10分钟访问网络读取一次,发现有变化则提醒。<BR><BR>每个URL占一行:<BR>";
   body+="<textarea style='width:690;height:250' id='urls'>"+urls+"</textarea><BR>";
   body+="<div align='center'><button onclick='JavaScriptHelper.Backback2MainPad(\"blog_demon_OnUrlListOk\",\""+this_.global_name+"\",document.getElementById(\"urls\").value);page_self.Close()'>确定</button></div>";
   body+="</body>";
   return body;
  };
  this_.browser.OpenHttpServer(true);  this_.browser.Navigate2("http://127.0.0.1:"+this_.browser.GetHttpServerPort());
  this_.browser.SetTitle("BLOG回复盯哨设置");
 },
 setHTML:function(this_){
  this_.browser.Show();
 },
 OnUrlListOk:function(this_,urls){
  this_.UrlList=new Array();
  var pos,q;
  pos=urls.indexOf("\n");
  q="delete from blogs";
  this_.db.query(q);
  while(pos>0){
   var url=urls.substr(0,pos);
   if(url.length>7){
    this_.UrlList.push(url);
    q="insert into blogs(url,html,html_len,status)values('"+url+"','',0,0)";
    this_.db.query(q);
   }
   urls=urls.substring(pos+1,urls.length);
   pos=urls.indexOf("\n");
  }
  url=urls;
  if(url.length>7){
   this_.UrlList.push(url);
   q="insert into blogs(url,html,html_len,status)values('"+url+"','',0,0)";
   this_.db.query(q);
  }
 },
 OnGetBody:function(client){
  if(__currentBlogDemon.currentGetBodyIndex<0)
   return;
  if(client.readyState==4){
   if(client.status==200){
    var txt=client.responseText;
    txt=replaceAll(txt,"\\","\\\\");
    txt=replaceAll(txt,"\"","\\\"");
    txt=replaceAll(txt,"\'","\\\'");
    
    var url=__currentBlogDemon.UrlList[__currentBlogDemon.currentGetBodyIndex];
    var q="select * from blogs where url='"+url+"'";
    var len=0;
    if(__currentBlogDemon.db.query("select * from blogs")){
     if(__currentBlogDemon.db.fetch()){
      len=__currentBlogDemon.db.get_array_data("html_len");
     }
    }    if(txt.length>len+10){//多了10个字就认为有回帖
     q="update blogs set html_len="+txt.length+",status=1";
     __currentBlogDemon.db.query(q);     q="update blogs set html='"+txt+"',status=2";
     __currentBlogDemon.db.query(q);     if(len>0){//不是首次收录
      //向消息列表追加
      var url=__currentBlogDemon.UrlList[__currentBlogDemon.currentGetBodyIndex];
      var mo={Type:"CUSTOM-BLOG-DEMON",line1:"回帖哨兵",line2:"有回复",line3:url,execute:"System.MyShellExecute('"+url+"');"};
      Messages.push(mo);
      Flicker();
     }
    }
   }
   if(__currentBlogDemon.currentGetBodyIndex+1<__currentBlogDemon.UrlList.length){
    __currentBlogDemon.currentGetBodyIndex++;
    var url=this_.UrlList[this_.currentGetBodyIndex];
    GetBody(url,__currentBlogDemon.OnGetBody);
   }else{
    __currentBlogDemon.currentGetBodyIndex=-1;    //干扰 XMLHTTP 缓冲
    var r=Math.round(Math.random()*10000)+1025;
    var url=__currentBlogDemon.UrlList[__currentBlogDemon.UrlList.length-1]+"abcdefg="+r;
    GetBody(url,__currentBlogDemon.OnGetBody);
   }
  }
 },
 OnTimer:function(this_){
  if(this_.currentGetBodyIndex>=0)return;//last task not finished
  if(this_.UrlList.length==0 || this_.currentGetBodyIndex>=this_.UrlList.length)return;//no more  __currentBlogDemon=this_;
  this_.currentGetBodyIndex++;
  var url=this_.UrlList[this_.currentGetBodyIndex];
  GetBody(url,this_.OnGetBody);
 }
}
// AJAX异步
function GetBody(url,response_func){
var client=new ActiveXObject("Msxml2.XMLHTTP");
if(response_func==undefined){
client.open("GET",url,false);
}else{
client.open("GET",url,true);
var rf=response_func;
client.onreadystatechange=function() {
if (client.readyState==4) {
if(rf!=undefined)
rf(client);
}
}
}
client.send();
}

解决方案 »

  1.   

    http://topic.csdn.net/u/20080508/14/51ab8e6a-8ef5-4ec5-aa23-0c9a92b15523.html 
      

  2.   

    想法不错,可惜就是代码太长了。
    据我所知,直接使用一个js库,如Microsoft Ajax,直接对一个页面进行Http Header请求,得到内容的长度,保存到数组中,下次再查询后,比较一下数组中指定索引上的值就可以了。其实没有必要进行一次完整的请求。