网络蜘蛛即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 }
三、如下截图就可以抓取到需要的信息