• 编写windows服务 定时爬取博客园文章 邮件提醒以及入库


    这段时间工作比较忙,每天也没那么多的时间逛博客园看文章,于是就想写一个工具 每天早上9点爬取文章给自己发邮件

    作为每天的技术早餐。

    相对而言,爬取博客园的文章还是比较简单的,主要思路就是分析博客园文章列表的分页,请求方式,页面渲染方式等,

    写篇随笔简单share一下。

    这个小工具主要用到的由nlog、HtmlAgilityPack、ef、quartz.net 。

    首先就是分析文章列表以及分页,当对文章列表切换页码的时候,

    url是这种形式: https://www.cnblogs.com/#p3

    p1 p2 p3 ...p(n) 刚开始我也是以为列表分页是靠这种形式走的,在url中传页码参数,用.net 的httpclient请求了几十页,

    发现返回内容都是一样的,这是一个坑,接着分析,F12分析一下,切换页码的时候发现是一个post请求,

    请求地址为:

    https://www.cnblogs.com/mvc/AggSite/PostList.aspx

    分析下请求参数,

    CategoryId、CategoryType、ItemListActionName、PageIndex、ParentCategoryId、TotalPostCount

    对每个参数的具体意义不做过多分析,pageindex就是页码,因此文章列表在分页的时候,请求地址为

    https://www.cnblogs.com/mvc/AggSite/PostList.aspx

    传递参数如:{"CategoryType":"SiteHome","ParentCategoryId":0,"CategoryId":808,"PageIndex":4,"TotalPostCount":4000,"ItemListActionName":"PostList"}

    按照此地址以及参数请求一下,确定能够返回期望结果,让人不舒服的地方又来了,返回结果非json 而是当前页面的html 。

    至此,分页请求方式已经解决了,下一步就是处理请求结果,获取请求页的文章列表内容。

    因为返回结果是html 我们首先看下文章列表页:

    在此列表内,我们能获取到的信息 有标题、作者、发布 时间、摘要,一般爬虫返回结果为json、html、xml等

    博客园返回结果为html,我们可以通过正则表达式去处理,Regex,也可以通过xpath去处理,因为返回结果就是一个html dom树,

    我们可以通过xpath语法去处理 http://www.w3school.com.cn/xpath/xpath_syntax.asp

    同时,我们也可以F12 Elements选项下 选择对应文章标题 右键copy  xpath 

     比如某一标题的xpath为  //*[@id="post_list"]/div[1]/div[2]/h3/a 

     相应的c#中 可以使用HtmlAgilityPack 这个工具来进行解析,代码如下:

                        HtmlDocument htmlDocument = new HtmlDocument();
                        htmlDocument.LoadHtml(html);
                        HtmlNodeCollection postItems = i == 1 ? htmlDocument.DocumentNode.SelectNodes("//*[@id='post_list']/*") : htmlDocument.DocumentNode.SelectNodes("./div");
    
                        foreach (HtmlNode item in postItems)
                        {
                            var titleNode = item.SelectSingleNode("./*/h3");
                            var footNode = item.SelectSingleNode("./*/div[@class='post_item_foot']");
                            if (Articles.Any(c => c.Title == titleNode.InnerText)) continue;
                            Articles.Add(new Article
                            {
                                Title = titleNode.InnerText,
                                ItemUrl = titleNode.FirstChild.Attributes["href"].Value,
                                Sumary = item.SelectSingleNode("./*/p").InnerText,
                                Author = footNode.SelectSingleNode("./a").InnerText,
                                PubDate = footNode.SelectSingleNode("./text()[2]").InnerText.Replace("发布于", "").Trim()
                            });
                        }


    其中的html就是当前列表的html内容,代码可自行写。Article为自定义的实体类 

    到这一步,文章的简单信息获取到了 url 标题 作者 发布时间 摘要

    下一步就是获取文章的内容

    比如某一文章的url为,https://www.cnblogs.com/senlinmu/p/9805684.html

    文章详情仍然采用HtmlAgilityPack

                    Articles.ForEach(v =>
                    {
                        string html = client.GetStringAsync(v.ItemUrl).Result;
                        htmlDocument.LoadHtml(html);
                        HtmlNode htmlNode = htmlDocument.DocumentNode.SelectSingleNode("//*[@id='cnblogs_post_body']");
                        v.Content = htmlNode?.InnerHtml;
                    });

    html为文章详情,此xpath为 //*[@id='cnblogs_post_body']

    至此,文章的标题、时间、摘要、内容获取完毕。

    然后就可给自己发邮件提醒。

    获取内容大致完成,下一步就是部署成windows服务 ,

      

  • 相关阅读:
    极大似然估计
    python模块的安装
    变异检测
    泰勒公式
    shell关于变量的操作
    Hadoop安装教程
    关于连接linux被拒
    靶向药
    层次聚类
    基因芯片原理
  • 原文地址:https://www.cnblogs.com/ZyCoder/p/9822510.html
Copyright © 2020-2023  润新知