一.介绍一个Http请求框架HttpCode.Core
HttpCode.Core 源自于HttpCode(传送门),不同的是 HttpCode.Core是基于.net standard 2.0实现的,移除了HttpCode与windows相耦合的api,且修改了异步实现,其余特性完全与HttpCode相同,大家 如果在使用中有什么问题可以查看在线文档(传送门)
HttpCode.Core完全开源,已传到github,地址:https://github.com/stulzq/HttpCode.Core
为了方便大家使用,也传到了nuget,地址:https://www.nuget.org/packages/HttpCode.Core/,在nuget中搜索 HttpCode.Core 或执行命令 Install-Package HttpCode.Core 就可以使用了。
具体的使用方法大家可以查阅在线文档,或者查看github。
简单、易用、高效 一个有态度的开源.Net Http请求框架!
二.分析抓取地址
首先使用谷歌浏览器的开发者工具,抓取博客园首页获取博文列表的地址:
从中我们可以分析出:
1. 请求地址 https://www.cnblogs.com/mvc/AggSite/PostList.aspx
2.请求方式 Post
3.请求数据
1 { 2 "CategoryType":"SiteHome", 3 "ParentCategoryId":0, 4 "CategoryId":808, 5 "PageIndex":3, 6 "TotalPostCount":4000, 7 "ItemListActionName":"PostList" 8 }
请求数据中,我们应当关心的是 PageIndex 代表的是 页数,我们可通过变换这个参数的值来获取不同页面的数据。
我们先使用HttpCode.Core来试一试获取数据:
int pageIndex = 1;//页数 HttpHelpers httpHelpers=new HttpHelpers(); HttpItems items=new HttpItems(); items.Url = "https://www.cnblogs.com/mvc/AggSite/PostList.aspx";//请求地址 items.Method = "Post";//请求方式 post items.Postdata = "{\"CategoryType\":\"SiteHome\"," + "\"ParentCategoryId\":0," + "\"CategoryId\":808," + "\"PageIndex\":"+ pageIndex + "," + "\"TotalPostCount\":4000," + "\"ItemListActionName\":\"PostList\"}";//请求数据 HttpResults hr = httpHelpers.GetHtml(items); Console.WriteLine(hr.Html); Console.ReadKey();
运行截图:
可以看到我们已经成功获取了数据,证明我们的分析是正确的。
三.解析返回的数据
刚刚我们测试接口返回的数据可以看出返回的是一堆html字符串。我们只想要博文的标题、作者、博文地址等等信息,我们不需要多余的html字符串,下面我们使用 HtmlAgilityPack 这个解析网页的组件来获得我们想要的数据。
关于这个组件的使用,博客园已经有不少介绍此组件的文档,大家可以搜索查看,使用此组件需具备xpath相关知识,我就不在此详细叙述了。
1.首先通过nuget安装 HtmlAgilityPack 组件
打开程序包控制台
执行命令 Install-Package HtmlAgilityPack -Version 1.5.2-beta6
2. 解析返回的数据
贴一下返回的部分数据:
从中我们不难看出每一个数据是以class=post_item的div来进行区分的,我们想要的博文地址、标题等是在这个div里面的class=post_item_body的div里面,以此类推我们可以分析出:
- 博文标题 <div class="post_item"> | <div class="post_item_body"> | h3 | a | Text
- 博文地址 <div class="post_item"> | <div class="post_item_body"> | h3 | a | href
- ..以此类推
因为HtmlAgilityPack是通过xpath来解析网页的,所以现在我们要根据我们上面分析出的路径来写xpath,这里不明白xpath的可以去w3cschool学习一下,非常简单。
下面是我写好的解析博文标题、地址和作者的代码,抓取其他信息可以自己参考试一试:
1 //解析数据 2 HtmlDocument doc=new HtmlDocument(); 3 //加载html 4 doc.LoadHtml(hr.Html); 5 6 //获取 class=post_item_body 的div列表 7 HtmlNodeCollection itemNodes = doc.DocumentNode.SelectNodes("div[@class='post_item']/div[@class='post_item_body']"); 8 9 //循环根据每个div解析我们想要的数据 10 11 foreach (var item in itemNodes) 12 { 13 //获取包含博文标题和地址的 a 标签 14 var nodeA = item.SelectSingleNode("h3/a"); 15 //获取博文标题 16 string title = nodeA.InnerText; 17 //获取博文地址 a标签的 href 属性 18 string url = nodeA.GetAttributeValue("href", ""); 19 20 //获取包含作者名字的 a 标签 21 var nodeAuthor = item.SelectSingleNode("div[@class='post_item_foot']/a[@class='lightblue']"); 22 string author = nodeAuthor.InnerText; 23 24 Console.WriteLine($"标题:{title} | 作者:{author} | 地址:{url}"); 25 }
运行截图:
四.循环抓取多个分页
前面我们分析出请求参数中的 PageIndex 是页数,分析单个页面的代码我们也写出来来,那么我们可以通过循环递增页数,来达到抓取不同分页数据的要求。
贴一下完整的代码
1 int pageIndex = 1;//页数 2 int maxPageIndex = 10;//最大页数 3 HttpHelpers httpHelpers=new HttpHelpers(); 4 5 for (int i = 0; i < maxPageIndex; i++) 6 { 7 HttpItems items = new HttpItems(); 8 items.Url = "https://www.cnblogs.com/mvc/AggSite/PostList.aspx";//请求地址 9 items.Method = "Post";//请求方式 post 10 items.Postdata = "{\"CategoryType\":\"SiteHome\"," + 11 "\"ParentCategoryId\":0," + 12 "\"CategoryId\":808," + 13 "\"PageIndex\":" + (i+1) + "," + //因为i从0开始 所以此处我们要加1 14 "\"TotalPostCount\":4000," + 15 "\"ItemListActionName\":\"PostList\"}";//请求数据 16 HttpResults hr = httpHelpers.GetHtml(items); 17 18 //解析数据 19 HtmlDocument doc = new HtmlDocument(); 20 //加载html 21 doc.LoadHtml(hr.Html); 22 23 //获取 class=post_item_body 的div列表 24 HtmlNodeCollection itemNodes = doc.DocumentNode.SelectNodes("div[@class='post_item']/div[@class='post_item_body']"); 25 26 Console.WriteLine($"第{i+1}页数据:"); 27 28 //循环根据每个div解析我们想要的数据 29 foreach (var item in itemNodes) 30 { 31 //获取包含博文标题和地址的 a 标签 32 var nodeA = item.SelectSingleNode("h3/a"); 33 //获取博文标题 34 string title = nodeA.InnerText; 35 //获取博文地址 a标签的 href 属性 36 string url = nodeA.GetAttributeValue("href", ""); 37 38 //获取包含作者名字的 a 标签 39 var nodeAuthor = item.SelectSingleNode("div[@class='post_item_foot']/a[@class='lightblue']"); 40 string author = nodeAuthor.InnerText; 41 //输出数据 42 Console.WriteLine($"标题:{title} | 作者:{author} | 地址:{url}"); 43 } 44 45 //每抓取一页数据 暂停三秒 46 Thread.Sleep(3000); 47 } 48 49 Console.ReadKey();
运行截图:
出处:https://www.cnblogs.com/stulzq/p/7474334.html
一个简单的.net core实现的简单爬虫就此完成!
Demo下载
https://files.cnblogs.com/files/stulzq/CnBlogsCrawler.zip