当前位置: 移动技术网 > IT编程>开发语言>.net > 编写windows服务 定时爬取博客园文章 邮件提醒以及入库

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

2018年10月22日  | 移动技术网IT编程  | 我要评论

马云老婆张瑛和儿子,丝诺萄官网,分类目录网站

这段时间工作比较忙,每天也没那么多的时间逛博客园看文章,于是就想写一个工具 每天早上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服务 ,

 

 

 

  

 

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网