Goolge搜索小偷详解版
帮你打造属于自己的搜索引擎---Google篇继续上次的百度篇,我们来看看Google。 一、认识Google搜索 Google搜索,全球最大搜索引擎,2004年8月在美国纳斯达克上市交易.Google从2000年开始提供中文搜索服务,目前是国内用户使用率仅次于百度的搜索引擎,提供网页、新闻、图片、论坛、本地等各种搜索 1、Google网页搜索的查询参数 必备参数 ☆ q--查询的关键词(Query),百度对应的参数为wd ☆ hl--Google搜索的界面语言(Interface Language) 常用的有: hl=zh-CN 简体中文语言界面,我们用的Google中文就是这个参数。 hl=zh-TW 繁体中文语言界面,港台地区常使用 hl=en 英文语言界面 ☆start--显示结果的页数,百度对应的参数为pn 可选参数 ☆ lr--搜索内容的语言限定(Language Restrict),限定只搜索某种语言的网页。如果lr参数为空,则为搜索所有网页。 常用的有: lr=lang_zh-CN 只搜索简体中文网页 lr=lang_zh-TW 只搜索繁体中文网页 lr=lang_zh-CN|lang_zh-TW 搜索所有中文网页 lr=lang_en 只搜索英文网页 ☆ ie--查询输入文字的编码(Input Encoding),Google缺省设置ie=utf-8,即请求Google搜索时参数q的值是一段utf-8编码的文字,如果要直接使用中文,可以设置ie=gb2312,即为简体中文编码 ☆ oe--搜索返回页面的编码(Output Encoding),Google缺省设置oe=utf-8 ☆ num--搜索结果显示条数(Number),取值范围在10--100条之间,缺省设置num=10,百度对应的参数为rn ☆ newwindow--是否开启新窗口以显示查询结果。 缺省设置newwindow=1,在新窗口打开网页 ☆ safe--安全搜索选项(SafeSearch),设置该参数可以过滤成人内容, 缺省设置safe为空,即不过滤成人内容,设置为safe=vss,即过滤成人内容。这个参数真是让一些人欢喜,让一些人忧。:) 2、Google网页搜索结果页面结构 和百度的很相似,按源代码结构自上而下为: 搜索框 赞助商链接 搜索结果 分页区 相关搜索 底部搜索框 版权区 其中“搜索结果、分页区”这两部分就是我们需要的有效数据。 二、核心函数--使用asp的xmlhttp组件 上一篇讲了一般的采集代码,在采集Google时有什么不同? 实际上采集百度和采集Google最大的不同在于,两者搜索结果返回页面使用的字符编码不同。百度作为中文搜索,其页面编码缺省是GB2312,使用xmlhttp的responseBody方法接受的数据是未解码的unsigned bytes数组,需要用相应函数转换为gb2312编码才能正常显示。而Google页面编码缺省是utf-8,恰好xmlhttp的responsetext方法返回的字符串缺省为utf-8编码的,所以我们可以直接使用responsetext方法返回Google数据,而无须编码转换了。 采集代码如下 set http=Server.createobject("MSXML2.XMLHTTP") Http.open "GET",url,false '打开xmlhttp Http.send() '发送请求 if Http.readystate<>4 then exit function end if getHTTPPage=Http.responsetext '直接返回utf-8编码结果 set http=nothing '释放xmlhttp 三、完整代码(文件名:searchi_gg1.asp 精简版) [Code Start] <% option explicit Dim start,keywords start = Request.QueryString("start") keywords = Request("keywords") '开始错误处理 On Error Resume Next If Err.Number <> 0 Then Response.Clear '显示错误信息给用户 Response.Write "<p align='center' ><font size=3> 出错了,请重新打开Google搜索.</font></p>" end if %> <HTML> <HEAD> <TITLE>Google搜索--<%=keywords%></TITLE> </HEAD> <STYLE type=text/css> <!-- body,td{font-family:arial} TD{FONT-SIZE:9pt;LINE-HEIGHT:18px} .cred{color:#FF0000} //--> </STYLE> <BODY leftmargin="0" topmargin="3" marginwidth="0" marginheight="0"> <table align="center" width="98%" cellspacing="0" cellpadding="0" border="0" bgcolor="#ffffff" > <tr> <form name="f1" method="post" action="searchi_gg1.asp"> <td width=150 height=50> 你的LOGO </td> <td align="left"> <input name=keywords size="40" maxlength="100" title="输入关键字,然后Let's Searching..." value="<%=keywords%>"> <input type="submit" value=" Google搜索[精简] "> </td></form></tr> </table> <% Dim strUrl,strTmp_gg,strInfo,strPage,strPageSum_gg,strQtime_gg Dim bNoResult_gg,regEx,patrn,strPage1 Dim strArray_ggTemp,iNa,i,strArray_gg(10) If keywords<>"" then 'Google查询字符串 strUrl ="http://www.google.com/search?hl=zh-CN&lr=lang_zh-CN&ie=gb2312&oe=UTF-8&sa=N&num=10&start="&start&"&q="&keywords '开始采集 strtmp_gg = GetHTTPPage(strUrl) ' 开始轮询服务器1,突破Google暂时屏蔽ip的问题 if strtmp_gg="0" then strUrl="http://216.239.39.99/search?hl=zh-CN&lr=lang_zh-CN&ie=gb2312&oe=UTF-8&sa=N&num=30&start="&start&"&q="&keywords strtmp_gg = GetHTTPPage(strUrl) ' 开始轮询服务器2 if strtmp_gg="0" Then strUrl="http://216.239.57.99//search?hl=zh-CN&lr=lang_zh-CN&ie=gb2312&oe=UTF-8&sa=N&num=30&start="&start&"&q="&keywords strtmp_gg = GetHTTPPage(strUrl) end if end if If InStr(strtmp_gg,"找不到和您的查询")<>0 or (InStr(strtmp_gg,"Server Error")<>0) Or strtmp_gg="0" Then bNoResult_gg=1 End If '截取"搜索结果"部分的内容 strinfo = strCut(strtmp_gg,"<div>","</div>",2) strArray_ggTemp = Split(strinfo,"<p class=g>") iNa=Ubound(strArray_ggTemp) '过滤掉Google快照和类似网页功能 for i = 1 to iNa strArray_gg(i) = "<font size=3><a"&strCut(strArray_ggTemp(i),"<a","- </font>",2)& "</font>" next set strArray_ggTemp=nothing '截取"分页区"部分的内容 strPage1 = strCut(strTmp_gg,"valign=bottom nowrap><font size=-1>","</table></div>",2) strPage1 = Replace(strPage1,"href=/search?","href=searchi_gg1.asp?keywords="&keywords&"&") '去除页码图片 patrn="<img.+?br>" strPage=regReplace(patrn,strPage1,"") patrn="<td.+?right>" strPage=regReplace(patrn,strPage,"") patrn="<td.+?nowrap>" strPage=regReplace(patrn,strPage," ") strPage=Replace(strPage,"</font>","") '结果数量与用时 strPageSum_gg=strCut(strtmp_gg,"有 <b>","</b> 项符合",2) strQtime_gg=strCut(strtmp_gg,"搜索用时 <b>","</b> 秒",2) Set strTmp_gg=nothing End If %> <!-- T1-Start --> <table cellspacing=0 cellpadding=0 border=0 width=98% align="center"> <tr valign=center align=middle height=18> <td width=1 bgcolor=#999999> <td nowrap style="FONT-WEIGHT:bold;COLOR:#ffffff;BACKGROUND-COLOR:#0033cc" width=64>互联网</td> <td align=right bgcolor=#eeeeee><nobr>找到符合<b><%=keywords%></b>的相关网页<b><%=strPageSum_gg%></b>篇,用时<b><%=strQtime_gg%></b>秒</nobr> </td> </tr> <tr><td bgcolor=#999999 colspan=3 height=2></td></tr></table> </td> </tr> </table> <% if keywords="" then Response.Write "<p align='center' ><font size=-1> 您好,请在搜索框中输入关键词.</font></p>" elseif bNoResult_gg=1 then Response.Write "<p align='center' ><font size=-1> 抱歉,未找到任何符合您查询条件的信息,请重新选择合适的关键词进行查询.</font></p>" else %> <table width="98%" align="center" cellspacing="0" cellpadding="0" border="0"> <tr> <td style=line-height:160% bgcolor="#ffffff" width="75%" valign=top><br> <% for i = 1 to iNa response.write strArray_gg(i)&"<br><br>" next %> </td> <td width="25%" valign=top><br> 这是你发挥的空间! </td> </tr> </table> <table width="98%" align="center" cellspacing="0" cellpadding="4" border="0"> <tr> <td align="center"> <br><font size=3><%=strPage%></font> </td> </tr> </table> <%End If Set strinfo=Nothing Set strArray_gg(10)=nothing %> <hr size="1" width="760" color="#0000ff"> <div align="center"><font size=-1> 程序更新请到这里<a href="http://www.zhihere.com/bbs/dispbbs.asp?boardid=8&id=605" target="_blank"><span class="cred">(知识分享论坛)</span></a>查看</font> </div> </BODY> </HTML> <% '采集函数 Function getHTTPPage(url) On Error Resume Next dim http set http=Server.createobject("MSXML2.XMLHTTP") Http.open "GET",url,false Http.send() if Http.readystate<>4 then exit function end if getHTTPPage=Http.responsetext set http=nothing If Err.number<>0 then getHTTPPage="0" 'Response.Write "<div align='center'><b>服务器获取文件内容出错</b></div>" Err.Clear End If End function '截取字符串,1.包括前后字符串,2.不包括前后字符串 Function strCut(strContent,StartStr,EndStr,CutType) Dim S1,S2 On Error Resume Next Select Case CutType Case 1 S1 = InStr(strContent,StartStr) S2 = InStr(S1,strContent,EndStr)+Len(EndStr) Case 2 S1 = InStr(strContent,StartStr)+Len(StartStr) S2 = InStr(S1,strContent,EndStr) End Select If Err Then strCute = "<p align='center' ><font size=-1>截取字符串出错.</font></p>" Err.Clear Exit Function Else strCut = Mid(strContent,S1,S2-S1) End If End Function '正则替换函数 Function regReplace(patrn,strSource,strReplace) Set regEx = New RegExp ' 建立正则表达式。 regEx.Pattern = patrn ' 设置模式。 regEx.IgnoreCase = true regEx.Global = true regReplace=regEx.replace(strSource,strReplace) Set regEx=nothing End Function %> [Code End] 把上面的代码Copy到记事本保存为searchi_gg1.asp,就可以使用了。如果你要更改文件名,请同时把以下代码中蓝色标识部分改为你的文件名 strPage = Replace(strPage,"href=s?","href=searchi_gg1.asp?") 几点说明: 1、Google反采集的手段相对多一些。 a、和百度一样,Google的结果页面代码也常常发生变化,有时在页面局部会出现动态的代码改变,所以要经常观察Google代码变化,根据实际情况改变相关的字符串标识。 b、Google反采集的主要手段就是暂时屏蔽用户IP,当一个用户频繁采集Google数据时,Google就会暂时屏蔽该用户的IP,导致用户无法访问Google,一般隔几分钟就会自己解除屏蔽。如何突破这种限制,在上面的代码中用到的是轮询服务器的方法,就是在几个Google服务器中轮换着查询,利用这中间的时间差克服屏蔽现象。但也有不少问题,比如,轮询多个服务器会导致查询时间过长,而且,我发现有时多个服务器同时进行屏蔽,所以,还要多尝试几个服务器地址,尽量保证它们之间没有多少关联性。 除了这种轮询的方法,还可以使用模拟http请求头的方法,我估计google这种屏蔽手法可能主要靠分析http请求头的数据判断是否为采集行为。可以利用xmlhttp的setrequestheader方法发送模拟的请求头信息,比如: http.setrequestheader "referer","http://so.163.com",模拟为163的搜索请求,我以前试过这种方法,管用了没几天就不行了,说明必须全面的进行模拟,由于http请求头的项目很多,也没具体研究,希望落伍的高人能指点一下。但这应该可以成为一种突破方向。 说了这种方法说了那种方法,实际最管用的方法就是就是和Google合作,一、技术上和google合作,自己申请一个Google API的key,然后用这个api做一个自己的搜索引擎,虽然有种种限制,比如Google限制一个key每天调用API的次数不超过一千次。但在其允许范围内肯定是不会屏蔽你IP的。 第二,金钱上和Google合作,只要掏钱给Google,一切问题都好解决了。哎,钱真是个好东西。:D 2、采集比较耗资源,所以程序中尽量早点释放变量或对象。如果你的空间资源不多,建议就不要搞这些了。 3、上边代码为精简版,下载包中含完整版的,可以根据你的需要进行选用。 点击下载此文件
|