Google 和 baidu 搜索结果二次加工

IE内核的浏览器中,js嵌入比较方便,只要通过函数execScript就可以在网页中插入JS代码,然后进一步进行操作。

本例通过提取搜索结果中的URL,发现 Google 和 baidu 指向同一个地址,则提取出来。对有效的搜索结果还可以加以记录,以便以后再有同样的搜索就能先找到之前搜集的有效结果,大大提高搜索效率。

 

下图一目了然地展示了其中的功能

 

不过,这些方便简单的功能要编写代码也着实花去不少功夫。

首先看看“此链接对于搜索有效”这个按钮怎插入到搜索结果中的:
(主体程序(即IE内核浏览器调用msscript.ocx)所用的js脚本和网页中的js脚本是两码事,这两个不同环境的脚本的变量和函数都是独立的,这一点在阅读的时候务必记住。网页的脚本的变量和函数在页面重新请求时就会消失,而使用msscript.ocx的IE内核浏览器中的js脚本则一直不发生变化。)

以 Google 为例

GoogleBrowser_OnNavigateComplete2
function GoogleBrowser_OnNavigateComplete2(url)
{
  the_href
="";
  js
="";
  js
+="function loopAllElements(node)\r\n";
  js
+="{\r\n";
    js
+="if(node.nodeType ==1)\r\n";
    js
+="{";
      js
+="if(node.tagName=='LI')\r\n";
      js
+="{";
        js
+="if(node.childNodes[0].tagName=='H3')\r\n";
        js
+="{\r\n";
          js
+="var a=node.childNodes[0].childNodes[0];\r\n";
          js
+="if(a.href!=undefined)\r\n";
          js
+="{\r\n";
            js
+="JavaScriptHelper.OnSearchItem('google',a.href,node.outerHTML,'"+SearchKeyText+"');\r\n";
            js
+="var button=document.createElement('INPUT');\r\n";
            js
+="button.type='BUTTON';\r\n";
            js
+="button.value='此链接对于搜索 \""+SearchKeyText+"\" 有效';\r\n";
            js
+="codeString='JavaScriptHelper.OnLike(\"'+a.href+'\",\""+SearchKeyText+"\");';\r\n";
            js
+="button.onclick=new Function(codeString);\r\n";
            js
+="node.appendChild(button);\r\n";
          js
+="}\r\n";
        js
+="}\r\n";
      js
+="}\r\n";
    js
+="}\r\n";
    js
+="var childrens=node.childNodes;\r\n";
    js
+="for(var i=0;i<childrens.length;i++)\r\n";
    js
+="{\r\n";
      js
+="loopAllElements(childrens[i]);\r\n";
    js
+="}\r\n";
  js
+="}\r\n";
  js
+="loopAllElements(document.getElementsByTagName('BODY')[0]);\r\n";
  js
+="JavaScriptHelper.OnOnePageFinish('google');\r\n";
  
//alert(js);
  gb.ExecuteJavascript(js);
}

 

 

下面是搜索下一页的代码

GotoNextPage
function GotoNextPage()
{
  SecondCount
--;
  
if(SecondCount>0)
  {
    labelCurrent.Caption
="当前第"+CurrentPageIndex+"页  "+SecondCount+"秒后自动下一页";
    setTimeout(
"GotoNextPage();",1000);
    
return;
  }
  
  PageStarted
=false;
  
  the_href
="";
  js
="var next_page_a;";
  js
+="function loopAllElements(node)\r\n";
  js
+="{\r\n";
    js
+="if(node.nodeType ==1)\r\n";
    js
+="{";
      js
+="if(node.innerText=='下一页')\r\n";
      js
+="{\r\n";
        js
+="if(node.href!=undefined)\r\n";
        js
+="{\r\n";
          js
+="next_page_a=node;\r\n";
          js
+="eval_code='the_href=\"';\r\n"
          js+="eval_code+=node.href;\r\n"
          js+="eval_code+=
'\"';\r\n"
          js
+="System.ExecuteScriptEval(eval_code,'Javascript');\r\n";
          js
+="return;\r\n";
        js
+="}\r\n";
      js
+="}\r\n";
    js
+="}\r\n";
    js
+="var childrens=node.childNodes;\r\n";
    js
+="for(var i=0;i<childrens.length;i++)\r\n";
    js
+="{\r\n";
      js
+="loopAllElements(childrens[i]);\r\n";
    js
+="}\r\n";
  js
+="}\r\n";
  js
+="next_page_a=null;\r\n";
  js
+="loopAllElements(document.getElementsByTagName('BODY')[0]);\r\n";
  gb.ExecuteJavascript(js);
  
if(the_href=="")
    
return;

  g_href
=the_href;

  the_href
="";
  bb.ExecuteJavascript(js);
  
if(the_href=="")
    
return;
    
  PageStarted
=0;

  b_href
=the_href;

  gb.Navigate2(g_href);
  bb.Navigate2(b_href);

  CurrentPageIndex
++;
  labelCurrent.Caption
="当前第"+CurrentPageIndex+"";

  
if(CurrentPageIndex>=MaxPageCount)
  {
    panelSearch.Enabled
=true;
  }
else
  {
    SecondCount
=20;
    setTimeout(
"GotoNextPage();",1000);
  }
}

 

当点击“此链接对于搜索有效”这个按钮的消息响应则是这段代码,它向数据库中的 LikeUrl 表插入一条记录:
function OnLike(url,keyword_text)
{
  q="INSERT INTO LikeUrl(key_text,url,short_desc)VALUES('"+keyword_text+"','"+url+"','')";
  db2.query(q);
 
  //重新刷新列表
  RefreshList();
}

 

有4个对象需要说明一下:

1 dvm

这是根对象,下面的对象都通过这个对象展开,例如System对象是System=dvm.GetSharedObject("System");得到的,JavaScriptHelper对象是通过JavaScriptHelper=dvm.GetSharedObject('JavaScriptHelper').GetCodeObject();得到的。

2 System

这个对象是主体EXE程序的对系那个,它早从EXE程序相关内容,例如System.Exit()就是退出,更多操作可以参照这个主体EXE程序的VC代码。

3 JavaScriptHelper

这个对象操纵msscript.ocx,他可以让网页中的js代码调用ocx中的js函数。

4 MiniBrowser

这个是建议浏览器的类,用它可以创建n可浏览窗口。MiniBrowser::InvokeFunction可以让ocx的js代码调用网页中的函数。

 

有兴趣的朋友可以展开整个代码看看

 

 

其中想说明的一点是,多个IE内核浏览器同时浏览的时候容易出现假死,而只要在繁重的JS计算代码中插入若干Sleep(0)让出处理机,则可防止90%以上的假死,不过使用过程中存在短暂时间不能动,不过大部分它会活过来的。Sleep(0)调用的是Windows API。下面是字符串替换函数,这是本例js计算最繁重的部分:如果用 


function replaceAll(text, s, t) {
  
var ss=s;
  
var tt=t;
  
var texttext=text;
  
var ret;
  
  ret
="";
  idx
=texttext.indexOf(ss);
  
while(idx>=0)
  {
    ret
+=texttext.substring(0,idx);
    ret
+=tt;
    texttext
=texttext.substring(idx+ss.length,texttext.length);
    idx
=texttext.indexOf(ss);
    
    
if(idx%5==0)Sleep(0);//牺牲性能,却能防止90%以上的假死
  }
  ret
+=texttext;
  Sleep(
0);//牺牲性能,却能防止90%以上的假死
  return ret;
};
function xmlencode(string) {
 
var str=string;
  str=replaceAll(str,'&','&amp;');
  str=replaceAll(str,'<','&lt;');
  str=replaceAll(str,'>','&gt;');
  str=replaceAll(str,'\'','&apos;');
  str=replaceAll(str,'"','&quot;');
 
return str;
}

 

不使用上述函数,而使用下面这个就极其容易假死:

function xmlencode(string) {
return string.replace(/\&/g,'&'+'amp;').replace(/</g,'&'+'lt;')
.replace(/>/g,'&'+'gt;').replace(/\'/g,'&'+'apos;').replace(/\"/g,'&'+'quot;');
}

 

【后记】google 和 baidu 已经很不错了,通过这2者相同的URL提取,则更加大大的提高准确性,不妨下一个玩玩吧

点击这里仅下载本例代码,下载后的.dwidget改名.zip文件解压即可

点击这里下载整个运行程序

点击这里下载这个IE内核浏览器源代码(不含msscript.ocx调用机制部分源代码,这部分是DLL形式提供的)

posted @ 2009-02-18 14:06  yesry  阅读(565)  评论(0编辑  收藏  举报