C#论坛-玄机论坛-C#论坛-玄机宝盒-玄机类库-C#

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 1889|回复: 4

[资源分享] .net core 实现简单爬虫—抓取博客园的博文列表

[复制链接]
  • TA的每日心情

    2017-6-19 15:59
  • 签到天数: 3 天

    [LV.2]【绿林好汉】

    辰晓晨 发表于 2017-9-5 17:03:56 | 显示全部楼层 |阅读模式

    玄机论坛-专业的C#交流论坛 交流QQ群: 16885911
    如有疑问,请加入官方群询问

    您需要 登录 才可以下载或查看,没有帐号?立即注册

    x
    本帖最后由 辰晓晨 于 2017-9-5 17:25 编辑

    一.介绍一个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请求框架!
    二.分析抓取地址
    首先使用谷歌浏览器的开发者工具,抓取博客园首页获取博文列表的地址:

    668104-20170904164647163-1555707456.png
    从中我们可以分析出:
    1. 请求地址  https://www.cnblogs.com/mvc/AggSite/PostList.aspx
    2.请求方式  Post
    3.请求数据
    [C#] 纯文本查看 复制代码
    {
        "CategoryType":"SiteHome",
        "ParentCategoryId":0,
        "CategoryId":808,
        "PageIndex":3,
        "TotalPostCount":4000,
        "ItemListActionName":"PostList"
    }

    请求数据中,我们应当关心的是  PageIndex  代表的是 页数,我们可通过变换这个参数的值来获取不同页面的数据。
    我们先使用HttpCode.Core来试一试获取数据:
    [C#] 纯文本查看 复制代码
    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();

    运行截图:
    668104-20170904165717116-1737839929.png
    可以看到我们已经成功获取了数据,证明我们的分析是正确的。

    三.解析返回的数据
    刚刚我们测试接口返回的数据可以看出返回的是一堆html字符串。我们只想要博文的标题、作者、博文地址等等信息,我们不需要多余的html字符串,下面我们使用  HtmlAgilityPack 这个解析网页的组件来获得我们想要的数据。
    关于这个组件的使用,博客园已经有不少介绍此组件的文档,大家可以搜索查看,使用此组件需具备xpath相关知识,我就不在此详细叙述了。
    1.首先通过nuget安装 HtmlAgilityPack  组件
      打开程序包控制台
      执行命令 Install-Package HtmlAgilityPack -Version 1.5.2-beta6
    2. 解析返回的数据
    贴一下返回的部分数据:
    [C#] 纯文本查看 复制代码
    <div class="post_item">
    <div class="digg">
        <div class="diggit"> 
        <span class="diggnum" id="digg_count_7470460">4</span>
        </div>
        <div class="clear"></div>
        <div id="digg_tip_7470460" class="digg_tip"></div>
    </div>      
    <div class="post_item_body">
        <h3><a class="titlelnk"  target="_blank">关于跨平台的一些认识</a></h3>                   
        <p class="post_item_summary">
    <a  target="_blank"><img width="48" height="48" class="pfs" src="//pic.cnblogs.com/face/918357/20161122225949.png" alt=""/></a>    前段时间看了 周志明的那本 《深入理解java虚拟机》。对于 平台无关性 问题,有了一些新的认识。所以特写一篇博客来进行总结。 这是我的第一篇不针对具体技术,而只针对计算机系统和原理的博客文章,而这种话题,总是比较宽泛,而我本人的水平有限,所以我也只能泛泛的写写,思考的不对的地方,还望读者不吝批评。 ...
        </p>              
        <div class="post_item_foot">                    
        <a  class="lightblue">eleven_yw</a> 
        发布于 2017-09-03 22:12 
        <span class="article_comment"><a  title="2017-09-04 15:23" class="gray">
            评论(2)</a></span><span class="article_view"><a  class="gray">阅读(210)</a></span></div>
    </div>
    <div class="clear"></div>
    </div>
    <div class="post_item">
    <div class="digg">
        <div class="diggit"> 
        <span class="diggnum" id="digg_count_7471197">0</span>
        </div>
        <div class="clear"></div>
        <div id="digg_tip_7471197" class="digg_tip"></div>
    </div>      
    <div class="post_item_body">
        <h3><a class="titlelnk"  target="_blank">2017年9月3日  实现网站的权限管理</a></h3>                   
        <p class="post_item_summary">
    <a  target="_blank"><img width="48" height="48" class="pfs" src="//pic.cnblogs.com/face/1224591/20170823222646.png" alt=""/></a>    现在各个企业管理网站对登录的账号都要进行权限管理,并且相当重要,每个账号登录进去所能看到的东西大不相同,下面是实现该功能的一个的一种方法。 需求: 权限:权限是使用者操作系统中功能模块的能力,如“角色管理”模块、“资费管 理”模块和“账单管理”模块等。通过指定权限,可将使用者的操作限定在指定的 范围 ...
        </p>              
        <div class="post_item_foot">                    
        <a  class="lightblue">Loseheart</a> 
        发布于 2017-09-03 21:34 
        <span class="article_comment"><a  title="" class="gray">
            评论(0)</a></span><span class="article_view"><a  class="gray">阅读(354)</a></span></div>
    </div>
    <div class="clear"></div>
    </div>
    从中我们不难看出每一个数据是以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学习一下,非常简单。
    下面是我写好的解析博文标题、地址和作者的代码,抓取其他信息可以自己参考试一试:
    [C#] 纯文本查看 复制代码
    //解析数据
    HtmlDocument doc=new HtmlDocument();
    //加载html
    doc.LoadHtml(hr.Html);
    
    //获取 class=post_item_body 的div列表
    HtmlNodeCollection itemNodes = doc.DocumentNode.SelectNodes("div[@class='post_item']/div[@class='post_item_body']");
    
    //循环根据每个div解析我们想要的数据
    
    foreach (var item in itemNodes)
    {
        //获取包含博文标题和地址的 a 标签
        var nodeA = item.SelectSingleNode("h3/a");
        //获取博文标题
        string title = nodeA.InnerText;
        //获取博文地址 a标签的 href 属性
        string url = nodeA.GetAttributeValue("href", "");
    
        //获取包含作者名字的 a 标签
        var nodeAuthor = item.SelectSingleNode("div[@class='post_item_foot']/a[@class='lightblue']");
        string author = nodeAuthor.InnerText;
    
        Console.WriteLine($"标题:{title} | 作者:{author} | 地址:{url}");
    }

    运行截图:
    QQ截图20170905170205.jpg

    四.循环抓取多个分页
    前面我们分析出请求参数中的 PageIndex  是页数,分析单个页面的代码我们也写出来来,那么我们可以通过循环递增页数,来达到抓取不同分页数据的要求。
    贴一下完整的代码
    [C#] 纯文本查看 复制代码
    int pageIndex = 1;//页数
    int maxPageIndex = 10;//最大页数
    HttpHelpers httpHelpers=new HttpHelpers();
    
    for (int i = 0; i < maxPageIndex; i++)
    {
        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\":" + (i+1) + "," + //因为i从0开始 所以此处我们要加1
                            "\"TotalPostCount\":4000," +
                            "\"ItemListActionName\":\"PostList\"}";//请求数据
        HttpResults hr = httpHelpers.GetHtml(items);
    
        //解析数据
        HtmlDocument doc = new HtmlDocument();
        //加载html
        doc.LoadHtml(hr.Html);
    
        //获取 class=post_item_body 的div列表
        HtmlNodeCollection itemNodes = doc.DocumentNode.SelectNodes("div[@class='post_item']/div[@class='post_item_body']");
    
        Console.WriteLine($"第{i+1}页数据:");
    
        //循环根据每个div解析我们想要的数据
        foreach (var item in itemNodes)
        {
            //获取包含博文标题和地址的 a 标签
            var nodeA = item.SelectSingleNode("h3/a");
            //获取博文标题
            string title = nodeA.InnerText;
            //获取博文地址 a标签的 href 属性
            string url = nodeA.GetAttributeValue("href", "");
    
            //获取包含作者名字的 a 标签
            var nodeAuthor = item.SelectSingleNode("div[@class='post_item_foot']/a[@class='lightblue']");
            string author = nodeAuthor.InnerText;
            //输出数据
            Console.WriteLine($"标题:{title} | 作者:{author} | 地址:{url}");
        }
    
        //每抓取一页数据 暂停三秒
        Thread.Sleep(3000);
    }
                
    Console.ReadKey();


    运行截图:
    668104-20170905092802585-355850243.gif

    一个简单的.net core实现的简单爬虫就此完成!

    Demo下载




    评分

    参与人数 1紫晶 +666 收起 理由
    君临 + 666 感谢分享,很给力!~

    查看全部评分

    玄机论坛-专业的C#交流论坛 交流QQ群: 16885911
    帖子内网盘失效后请使用下面地址

    http://bbs.msdn5.com/thread-1218-1-1.html
    如果失效请联系站长重新分享
    回复

    使用道具 举报

  • TA的每日心情
    郁闷
    2018-5-12 18:34
  • 签到天数: 1 天

    [LV.1]【初入江湖】

    zifeng 发表于 2017-9-20 01:02:46 | 显示全部楼层
    111111166666666666666666
    玄机论坛-专业的C#交流论坛 交流QQ群: 16885911
    帖子内网盘失效后请使用下面地址

    http://bbs.msdn5.com/thread-1218-1-1.html
    如果失效请联系站长重新分享
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    无聊
    2016-11-16 10:03
  • 签到天数: 1 天

    [LV.1]【初入江湖】

    YoGalin 发表于 2017-10-18 11:54:12 | 显示全部楼层
    感谢分享,很给力!~
    玄机论坛-专业的C#交流论坛 交流QQ群: 16885911
    帖子内网盘失效后请使用下面地址

    http://bbs.msdn5.com/thread-1218-1-1.html
    如果失效请联系站长重新分享
    回复 支持 反对

    使用道具 举报

  • TA的每日心情

    2016-12-14 23:59
  • 签到天数: 1 天

    [LV.1]【初入江湖】

    不会飞的超人 发表于 2018-4-21 11:00:13 | 显示全部楼层
    哪里下载?
    玄机论坛-专业的C#交流论坛 交流QQ群: 16885911
    帖子内网盘失效后请使用下面地址

    http://bbs.msdn5.com/thread-1218-1-1.html
    如果失效请联系站长重新分享
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2018-4-25 09:51
  • 签到天数: 2 天

    [LV.1]【初入江湖】

    学习socket 发表于 2018-4-25 09:59:27 | 显示全部楼层
    爬虫就是抓取数据吗
    玄机论坛-专业的C#交流论坛 交流QQ群: 16885911
    帖子内网盘失效后请使用下面地址

    http://bbs.msdn5.com/thread-1218-1-1.html
    如果失效请联系站长重新分享
    回复 支持 反对

    使用道具 举报

    *滑动验证:
    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    关闭

    站长推荐上一条 /2 下一条

    QQ|Archiver|手机版|小黑屋|玄机论坛   

    GMT+8, 2018-9-23 14:33 , Processed in 0.622920 second(s), 27 queries .

    Powered by Msdn5.com

    © 2014-2015 Msdn5 Inc.

    快速回复 返回顶部 返回列表