網絡蜘蛛即Web Spider,是一個很形象的名字。把互聯網比喻成一個蜘蛛網,那么Spider就是在網上爬來爬去的蜘蛛。網絡蜘蛛是通過網頁的鏈接地址來尋找網頁,從 網站某一個頁面(通常是首頁)開始,讀取網頁的內容,找到在網頁中的其它鏈接地址,然后通過這些鏈接地址尋找下一個網頁,這樣一直循環下去,直到把這個網 站所有的網頁都抓取完為止。如果把整個互聯網當成一個網站,那么網絡蜘蛛就可以用這個原理把互聯網上所有的網頁都抓取下來。
對於搜索引擎來說,要抓取互聯網上所有的網頁幾乎是不可能的,從目前公布的數據來看,容量最大的搜索引擎也不過是抓取了整個網頁數量的百分之四十左右。這 其中的原因一方面是抓取技術的瓶頸,無法遍歷所有的網頁,有許多網頁無法從其它網頁的鏈接中找到;
另一個原因是存儲技術和處理技術的問題,如果按照每個頁 面的平均大小為20K計算(包含圖片),100億網頁的容量是100×2000G字節,即使能夠存儲,下載也存在問題(按照一台機器每秒下載20K計算, 需要340台機器不停的下載一年時間,才能把所有網頁下載完畢)。同時由於數據量太大,在提供搜索時也會有效率方面的影響。因此,許多搜索引擎的網絡蜘 蛛只是抓取那些重要的網頁,而在抓取的時候評價重要性主要的依據是某個網頁的鏈接深度。
【以下示例以:http://www.cppi.cn 站點為例,爬取該站點下的紅色截圖部分信息行業新聞信息】
一、模擬請求,獲取網頁Html並且下載html
1.1首先通過瀏覽器查看訪問網站的所有參數信息。
代碼模擬請求時需要傳遞的所有參數信息都可包含在以下截圖紅色圈出部分,但並不一定需要保持和瀏覽端一樣的參數。
1.2代碼實現,模擬請求
1 private string GetHtml(string Url) //:Url="http://www.cppi.cn"; 2 { 3 string Html = string.Empty; 4 HttpWebRequest Request = HttpWebRequest.Create(Url) as HttpWebRequest; 5 Request.Timeout = 3000; 6 Request.ContentType = "text/html;charset=utf-8"; 7 Encoding encode = Encoding.GetEncoding("GB2312"); 8 using (HttpWebResponse response = Request.GetResponse() as HttpWebResponse) 9 { 10 if (response.StatusCode == HttpStatusCode.OK) 11 { 12 try 13 { 14 StreamReader stream = new StreamReader(response.GetResponseStream(), encode); 15 Html = stream.ReadToEnd(); 16 } 17 catch (System.Exception ex) 18 { 19 throw ex; 20 } 21 } 22 } 23 return Html; 24 }
二、篩選數據
獲取到Html內容后,需要從整個Html內容中篩選過濾得到我們業務需要的數據。以下基於HtmlAgilityPack第三方組件,使用Path來解析HTML。
HtmlAgilityPack是.net下的一個HTML解析類庫,具體使用詳見 【https://www.cnblogs.com/mq0036/p/11705424.html】
2.1 通過瀏覽器端,鎖定需要顯示的信息對應的Xpath路徑
通瀏覽器訪問站點[http://www.cppi.cn],鼠標右鍵---檢查,鼠標定位到需要顯示的節點,右鍵---Copy-----Copy Xpath
即可得到對應的Xpath路徑:/html/body/div[8]/div[2]/ul/li
2.2 通過Xpath解析Html獲取信息 using HtmlAgilityPack;
1 public ApiResponseModel<IndustrynewsResponse> CrawlerIndustrynews() 2 { 3 string Url = ConfigurationManager.AppSettings.Get("NewsUrl"); 4 List<Industrynews> Industrynewslst = new List<Industrynews>(); 5 var Industrynews = new IndustrynewsResponse(); 6 string html = GetHtml(Url); //:模擬請求獲取到整個Html內容 7 if (!string.IsNullOrWhiteSpace(html)) 8 { 9 HtmlDocument htmlDoc = new HtmlDocument(); 10 htmlDoc.LoadHtml(html); 11 if (htmlDoc != null) 12 { 13 string maintitleXpath = "/html/body/div[8]/div[2]/h1[2]/a"; 14 HtmlNode maintitleNode = htmlDoc.DocumentNode.SelectSingleNode(maintitleXpath); 15 if (maintitleNode != null) 16 { 17 Industrynews.NewsMainhref = Url + maintitleNode.Attributes["href"].Value; 18 Industrynews.NewsMainTitle = maintitleNode.InnerText; 19 } 20 string secondtitleXpath = "/html/body/div[8]/div[2]/p[2]"; 21 HtmlNode SecondTitleNode = htmlDoc.DocumentNode.SelectSingleNode(secondtitleXpath); 22 if (SecondTitleNode != null) 23 { 24 Industrynews.SecondTitle = SecondTitleNode.InnerText; 25 } 26 string FocusXpath = "/html/body/div[8]/div[2]/ul/li"; 27 HtmlNodeCollection htmlNode = htmlDoc.DocumentNode.SelectNodes(FocusXpath); //:該Xpath下有多個子節點,所以此處獲取到所有的節點信息 28 if (htmlNode != null) 29 { 30 foreach (var node in htmlNode)//:循環子節點獲取每個子節點對應信息 31 { 32 HtmlDocument docChild = new HtmlDocument(); 33 docChild.LoadHtml(node.OuterHtml); 34 HtmlNode urlNode = docChild.DocumentNode.SelectSingleNode("li/a"); //獲取a標簽 35 if (docChild != null) 36 { 37 Industrynews industrynews = new Industrynews() 38 { 39 href = Url + urlNode.Attributes["href"].Value, //獲取a標簽對應的href屬性
40 Text = urlNode.InnerText //:獲取標簽text顯示文本 41 }; 42 Industrynewslst.Add(industrynews); 43 } 44 } 45 Industrynews.IndustrynewsList = Industrynewslst; 46 } 47 return new ApiResponseModel<IndustrynewsResponse> { Code = (int)HttpStatusCode.OK, Message = "", Data = Industrynews }; 48 } 49 else 50 { 51 return new ApiResponseModel<IndustrynewsResponse> { Code = (int)HttpStatusCode.BadRequest, Message = "ErrorLoadHtml", Data = null }; 52 } 53 } 54 else 55 { 56 return new ApiResponseModel<IndustrynewsResponse> { Code = (int)HttpStatusCode.BadRequest, Message = "ErrorLoadHtml", Data = null }; 57 } 58 }
三、如下截圖就可以抓取到需要的信息