整理一下最近做的幾個項目。總結幾個用到的知識點和關鍵區段代碼,以供大家學習交流。 1、爬蟲抓取網頁內容資訊。可以用System.Net.WebRequest、webclient等類來處理。 2、對於某些動態網頁,產生頁面信心由javascript動態產生連結資訊的。也可以進行分析傳值的方式,在post的時候將參數帶進去(大多數網站的參數是有規則的)。實在不行也可以使用webbrowser控制項,類比點擊。或傳值。 以http://www.aslan.com.cn/Code.aspx網站為例。 部分代碼如下:
//使用webbrowser訪問指定網頁。address為網頁地址
private void Navigate(WebBrowser web,String address) { if (String.IsNullOrEmpty(address)) return; if (address.Equals("about:blank")) return; if (!address.StartsWith("http://")) address = "http://" + address; try { web.Navigate(new Uri(address)); } catch (System.UriFormatException) { return; }
}
由於要抓取網頁內容及在載入完畢後提交參數所以需要驗證載入完畢即DocumentCompleted。而在實際使用過程當中,發現在一個頁面的載入過程中可能會有多次DocumentCompleted,所以在這裡採用+1、-1的方式來判斷是否載入完畢。
首先在formload中綁定網頁載入完畢事件。
private void getCode3webBrowser_Load(object sender, EventArgs e)<br /> {</p><p> string address = "http://www.aslan.com.cn/Code.aspx";<br /> this.Navigate(webBrowser1, address);<br /> webBrowser1.Navigated += new WebBrowserNavigatedEventHandler(webBrowser_Navigated);<br /> webBrowser1.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(webBrowser_DocumentCompleted);<br /> }
並且定義標示count
int count = 0;然後在每次導航後給標示+1 private void webBrowser_Navigated(object sender, WebBrowserNavigatedEventArgs e)<br /> {<br /> count++;<br /> }
在每次DocumentCompleted中給count-1,最後當count=0時即表示頁面載入完畢。可以進行對頁面資訊的處理等操作了。
private void webBrowser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e) { count = count - 1; string eventTarget = "dg_Code$ctl24$ctl"; if (0 == count && isComplete == false && j<=10) { eventTarget = eventTarget + getPage(j); if (!isLastPage(webBrowser1)) { InvokeScriptMethod(webBrowser1, eventTarget, ""); } else { MessageBox.Show("抓取完畢"); } postComplete = true; j++; } else if (postComplete == true) { dealWithByDOM(webBrowser1); postComplete = false; } else if (0 == count && isComplete) { System.Windows.Forms.HtmlDocument htdoc = webBrowser1.Document; for (int i = 0; i < htdoc.All.Count; i++) { if (htdoc.All[i].Name == "btn_search") { htdoc.All[i].InvokeMember("click");//引發”CLICK”事件 isComplete = false; break; } } } }
剩下的就是對html的分析,如何在茫茫多的html代碼中找到我們需要的資訊呢?在這裡我是通過HtmlAgilityPack類來處理html內容提取的。
其中HtimlAgilityPack類是codeplex上的提供的一個類,http://htmlagilitypack.codeplex.com/用來處理html檔案還是非常不錯的(個人感覺挺好用)
private void dealWithByDOM(WebBrowser webBro)<br /> {<br /> HtmlAgilityPack.HtmlDocument htmlDoc = new HtmlAgilityPack.HtmlDocument();</p><p> htmlDoc.LoadHtml(webBro.DocumentText);<br /> HtmlNode Node1 = htmlDoc.GetElementbyId("dg_Code_ctl03_Label5");<br /> HtmlNode Node2 = htmlDoc.GetElementbyId("dg_Code_ctl03_Label6");<br /> HtmlNode Node3 = htmlDoc.GetElementbyId("dg_Code_ctl03_Label7");<br /> HtmlNode Node4 = htmlDoc.GetElementbyId("dg_Code_ctl03_Label8");<br /> HtmlNode Node5 = htmlDoc.GetElementbyId("dg_Code_ctl03_Label9");</p><p> DataRow dr = dt_finallyResult.NewRow();<br /> dr["三字碼"] = Node1.InnerText;<br /> dr["城市碼"] = Node2.InnerText;<br /> dr["城市中文名"] = Node3.InnerText;<br /> dr["城市英文名"] = Node4.InnerText;<br /> dr["國家"] = Node5.InnerText;<br /> dt_finallyResult.Rows.Add(dr);<br /> dataGridView1.DataSource = dt_finallyResult;<br /> }
以上就是該程式的部分實現代碼。最後如下:(不過不到萬不得已最好不要使用webbrowser的方式做爬蟲,它的速度太慢了,我要抓取的資訊只有286頁,可是花了我將近10分鐘的時間)
下面是程式運行:(為了展示方便,左邊為webBrowser控制項導航到目標網站的結果,右邊dataGridview為抓取後經過提取的所需資訊。)