现在的位置: 首页 > 综合 > 正文

C#如何抓取网页数据、分析并且去除Html标签

2013年06月08日 ⁄ 综合 ⁄ 共 3558字 ⁄ 字号 评论关闭

      由于自己的搜索引擎中做到了这一块内容,所以今天说说如何抓取网页数据、分析并且去除Html标签,给大家提供一个参考。我的平台是Visual Studio2005C#

——————————————————————————————————————————————

  首先将网页内容整个抓取下来,假设抓取的数据放在RecvBuffer这个byte[]中(数据从网络上传输过来时不是字符串的形式而是byte),那么我们的第一步就是将RecvBuffer转化为String,以便于对其操作,实例如下:

  // 将接收到的数据增加到响应字符串中

   strResponse += Encoding.ASCII.GetString(RecvBuffer, 0, nBytes);

       strResponse即是保存数据的字符串,此处用系统自带的System.Text.Encoding的方法转化 RecvBufferGetString的第一个参数RecvBuffer就是我们的原始数据,即包含需要解码的字节序列的字节数组;第二个参数0代表第一个要解码的字节的索引,一般就从0开始;第三个参数nBytes为要解码的字节数,可以自己调整。

       得到了数据的字符串形式,然后可以对网页进行解析了(其实就是对字符串的各种操作和正则表达式的应用)。下面我以几个例子来说明对网页数据的解析:

  // 解析页面,查找链接

  // 此处尚需扩展,还有某些形式的链接不被识别

  string strRef = @"(href|HREF|src|SRC|action|ACTION|Action)[ ]*=[ ]*[""'][^""'#>]+[""']";

   MatchCollection matches = new Regex(strRef).Matches(strResponse);

   strStatus += "找到: "+matches.Count+" 个链接"r"n";

       上面的例子将网页中的链接解析出来,strRef变量表示了正则表达式的模式,变量matches表示符合匹配的项目的集合,后面的 Regex(strRef).Matches(strResponse)就是创建正则规则使得strResponse里符合strRef模式的字符串都返回。然后调用matches的变量就可以取得各种信息了。

       当然,这里只能识别一些基本的链接形式,像script中的链接和一些不带“”的链接都没有被支持,这个的扩展还是蛮简单的。

       再举几个更简单点的解析的例子,大家学习学习:

  //获取标题

   Match TitleMatch = Regex.Match(strResponse, "<title>([^<]*)</title>", RegexOptions.IgnoreCase | RegexOptions.Multiline);

   title = TitleMatch.Groups[1].Value;

 

  //获取描述信息

   Match Desc = Regex.Match(strResponse, "<Meta name=""DESCRIPTION"" content=""([^<]*)"">", RegexOptions.IgnoreCase | RegexOptions.Multiline);

   strdesc = Desc.Groups[1].Value;

 

  //获取网页的大小

   size = strResponse.Length;

——————————————————————————————————————————————

       好了,下面说一下如何去除Html标签,这个想必有很多初学者很需要。其实还是正则表达式和字符串基本操作的应用,由于这个功能还是比较常用的,所以例子写成了函数,便于调用:

  /**//// <summary>

  /// Html标签转化为空格

  /// </summary>

  /// <param name="strHtml">待转化的字符串</param>

  /// <returns>经过转化的字符串</returns>

  private string stripHtml(string strHtml)

  {

      Regex objRegExp = new Regex("<(.|"n)+?>");

     string strOutput = objRegExp.Replace(strHtml, "");

      strOutput = strOutput.Replace("<", "&lt;");

      strOutput = strOutput.Replace(">", "&gt;");

     return strOutput;

   }

       ok,这样一来Html标签就基本没了,但是有些例外会使得去除不干净,所以建议连续两次转化,这样就搞定了。但是还没结束,如果你留意的话,可以看到上面的函数其实是将Html标签转化为了空格。太多连续的空格会影响之后对字符串的操作。所以再加入这样的语句:

  //把所有空格变为一个空格

   Regex r = new Regex(@""s+");

   wordsOnly = r.Replace(strResponse, " ");

   wordsOnly.Trim();

       好了,大功告成,这里的wordsOnly便是我们最终的成果----去除了Html标签,并去除了多余空格的字符串。

大家知道,用HttpWebRequest可以通过Http对网页进行抓取,但是如果是内网,而且是通过代理上网的用户,如果直接进行操作是行不通的。
那有没有什么办法呢?
当然有,呵呵,见以下代码:

string urlStr = "http://www.domain.com";                            //設定要獲取的地址

HttpWebRequest hwr = (HttpWebRequest)HttpWebRequest.Create(urlStr);    //建立HttpWebRequest對象

hwr.Timeout = 60000;                                                //定義服務器超時時間

WebProxy proxy = new WebProxy();                                    //定義一個網關對象

proxy.Address = new Uri("http://proxy.domain.com:3128");            //網關服務器:端口

proxy.Credentials = new NetworkCredential("f3210316", "6978233");    //用戶名,密碼

hwr.UseDefaultCredentials = true;                                    //啟用網關認証

hwr.Proxy = proxy;                                                    //設置網關

HttpWebResponse hwrs = (HttpWebResponse)hwr.GetResponse();            //取得回應

Stream s = hwrs.GetResponseStream();                                //得到回應的流對象

StreamReader sr = new StreamReader(s, Encoding.UTF8);                //UTF-8編碼讀取流

StringBuilder content = new StringBuilder();                        //

while (sr.Peek() != -1)                                                //每次讀取一行,直到

{                                                                    //下一個字節沒有內容

     content.Append(sr.ReadLine()+""r"n");                            //返回為止

}  

return content.ToString() ;                                            //返回得到的字符串

 

抱歉!评论已关闭.