由於自己的搜尋引擎中做到了這一塊內容,所以今天說說如何抓取網頁資料、分析並且去除Html標籤,給大家提供一個參考。我的平台是Visual Studio2005,C#。
—————————————————————割—————————————————————————
首先將網頁內容整個抓取下來,假設抓取的資料放在RecvBuffer這個byte[]中(資料從網路上傳輸過來時不是字串的形式而是byte),那麼我們的第一步就是將RecvBuffer轉化為String,以便於對其操作,執行個體如下:
// 將接收到的資料增加到響應字串中
strResponse += Encoding.ASCII.GetString(RecvBuffer, 0, nBytes);
strResponse即是儲存資料的字串,此處用系統內建的System.Text.Encoding的方法轉化 RecvBuffer,GetString的第一個參數RecvBuffer就是我們的未經處理資料,即包含需要解碼的位元組序列的位元組數組;第二個參數0代表第一個要解碼的位元組的索引,一般就從0開始;第三個參數nBytes為要解碼的位元組數,可以自己調整。
得到了資料的字串形式,然後可以對網頁進行解析了(其實就是對字串的各種操作和Regex的應用)。下面我以幾個例子來說明對網頁資料的解析:
// 解析頁面,尋找連結
// 此處尚需擴充,還有某些形式的連結不被識別
string strRef = @"(href|HREF|src|SRC|action|ACTION|Action)[ ]*=[ ]*[""'][^""'#>]+[""']";
MatchCollection matches = new Regex(strRef).Matches(strResponse);
strStatus += "找到: "+matches.Count+" 個連結"r"n";
上面的例子將網頁中的連結解析出來,strRef變數表示了Regex的模式,變數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標籤,這個想必有很多初學者很需要。其實還是Regex和字串基本操作的應用,由於這個功能還是比較常用的,所以例子寫成了函數,便於調用:
/**//// <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("<", "<");
strOutput = strOutput.Replace(">", ">");
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() ; //返回得到的字串