基于Google Search的站内搜索,C#自定义正则解析
需求如图:网站里的一个搜索功能,需要进行站外搜索.这里我用到了Google 搜索.
自定义搜索地址: http://www.google.com/custom? 用.com的,cn搜索结果页面里夹杂了一些广告,不利于解析.
搜索里输入网站+关键字,做过seo的朋友都知道site:是什么意思,这样搜索的结果全是google收录的你的网站带有搜索关键字的结果.
搜索的url:
http://www.google.com/custom?hl=en&newwindow=1&q=site:www.hx-soft.cn++档案数字化&btnG=Google+搜索
默认的参数就是这些,当然还有其它一些参数.
其它参数详细信息请参考:
http://blog.csdn.net/hean/archive/2008/03/03/2142689.aspx
搜索页面的结果,我只需要两部分:
这一部分需要获取搜索结果的总数,即这里的42.
这一部分就是主要的搜索结果列表了.要的就是这些,大致步骤先download搜索页面的html源码,再通过正则解析获取自己想要的部分.
首先建一个SearchByGoogle静态类,添加方法:
/// <summary> /// 根据url获取远程html源码 /// </summary> /// <param name="url">搜索url</param> /// <returns>返回DownloadData</returns> public static string GetSearchHtml(string url) { WebClient MyWebClient = new WebClient(); MyWebClient.Credentials = CredentialCache.DefaultCredentials; //获取或设置用于对向Internet资源的请求进行身份验证的网络凭据。 Byte[] pageData = MyWebClient.DownloadData(url); //从指定url下载数据 return Encoding.UTF8.GetString(pageData); //获取网站页面采用的是UTF-8 }
这个方法根据url拿到html,就可以开始解析了,添加一个获取搜索结果总数的方法:
/// <summary> /// 判断搜索到结果的总条数 /// </summary> /// <param name="pageHtml">DownloadData</param> /// <returns>结果数目</returns> public static int IsExistResult(string pageHtml) { int count = 0; //结果数目 Regex reg = new Regex(@"of(?:\sabout)? <b>(\d+)</b> from"); //分析结果正则表达式 if (reg.IsMatch(pageHtml)) { Match m = reg.Match(pageHtml); if (m.Groups.Count >= 2) { count = int.Parse(m.Groups[1].Value); } } return count; }
因为这里还涉及到一个对结果的分页,每页10条,上面方法可以判断是否搜索到结果. 通过count总数,可建立分页参数.
分析url分页:
http://www.google.com/custom?hl=en&newwindow=1&q=site:www.hx-soft.cn++档案数字化&start=10&sa=N
这是第二页,有个参数start=10,第一页start=0,依次第三页是start=20
添加方法如下:
/// <summary> /// 获取搜索结果分页起始位置 /// </summary> /// <param name="count">结果数目</param> /// <returns>返回包含分页起始位置的数组</returns> public static int[] GetPageStarts(int count) { //计算页码数 int pageTotal = 0; pageTotal = count % 10 == 0 ? count / 10 : (count / 10) + 1; //分页起始数 int[] starts = new int[pageTotal]; for (int i = 0; i < pageTotal; i++) { starts[i] = i * 10; } return starts; }
这里建立了一个数组包含分页的start参数,以备在自己建立的搜索结果页面添加LinkButton.
最后就是要解析出中间的列表,好在搜索页面里没有Link的样式,就直接用它的head里的样式了,这里只需要解析出中间那块.
还需要去掉列表里的Cached Similar,如上图红框部分.添加方法:
/// <summary> /// 获取搜索页面的条目html /// </summary> /// <param name="pageHtml">DownloadData</param> /// <returns>返回条目列表html</returns> public static string GetSearchContent(string pageHtml) { //抓取中间的列表内容[<ol></ol>] string olStr = ""; Regex regOl = new Regex("<ol style=\\\"margin:0;padding:0;list-style:none\\\">(.+)</ol>"); if (regOl.IsMatch(pageHtml)) { Match mNobr = regOl.Match(pageHtml); if (mNobr.Groups.Count >= 2) { olStr = mNobr.Groups[0].Value; } } //过滤不需要字符串[Cached Similar] string nobr = ""; Regex regNobr = new Regex("- </span><nobr><a class=fl href=\".{0,255}\" target=_blank>Cached</a>" + "( - <a href=\".{0,255}\" class=\"fl\">Similar</a>)?</nobr>"); if (regNobr.IsMatch(olStr)) { nobr = regNobr.Replace(olStr, "</span>"); } return nobr; }
到这里,想要的内容都已得到了,只需要在你要使用的地方调用了.调用示例:
//获取搜索框文本 string _searchKeyWord = this.txtSearch.Text; //请求URL string url = "http://www.google.com/custom?hl=en&newwindow=1&q=" + _searchKeyWord + "+site%3Awww.hx-soft.cn&btnG=Search"; try { string pageHtml = SearchByGoogle.GetSearchHtml(url); int count = SearchByGoogle.IsExistResult(pageHtml); if (count > 0) { int[] starts = SearchByGoogle.GetPageStarts(count); string content = SearchByGoogle.GetSearchContent(pageHtml); } else { //没有搜索到指定内容 } }接下来只需要传入你需要的参数就可以弄出想要的搜索结果了.初学正则,做的一点小东西.希望与大家交流,不到之处还请指出!