使用Nodejs获取自己所有的CSDN博客附源码与效果图

举报
拿我格子衫来 发表于 2022/03/18 01:10:51 2022/03/18
【摘要】 最近一直在想着做一个自己博客的数据统计。做数据统计,报表,必须要先有数据,于是写了一个使用Nodejs获取自己CSDN所有博客链接的程序, 并将这些博客数据通过页面展示出来。 先看下效果图 下面说一下做...

最近一直在想着做一个自己博客的数据统计。做数据统计,报表,必须要先有数据,于是写了一个使用Nodejs获取自己CSDN所有博客链接的程序,
并将这些博客数据通过页面展示出来。
先看下效果图

下面说一下做这个程序的具体历程,一方面是自己的总结,一方面是与大家探讨如何使用自己掌握的技术解决自己的难题

分析需求

做一个程序前,我们首先要思考的问题是,这个程序是要解决什么问题,如果问题过于大,耗费时间长,代功复杂,那么这个问题是否可以分成几部分来完成,自己有什么技能能够完成这项任务。很多软件之所以没有成功是因为设定的目标过大,而又没有支撑这个大计划的步骤,很多在孵化时期就夭折了。如果你的软件是一个人做,而你有没有太多时间,那么首先你要列出一个最小的功能集,这个功能集是这个软件的核心功能,实现了它就能让人快速了解你的产品有什么特点。
开始分析需求,
首先,要做到功能通用我们必须提供一个输入博客首页的地方,输入博客地址,点击开始按钮,将地址发送给后端,后端根据地址,获取页面,并进行获取所有博客所有文字的地址,文章的标题。后端获取后,将数据格式化,并返回前端,前端使用数据,展示到用户页面上。软件的第一此迭代需求做到这一步就行了。文章的阅读数,点赞数,收藏数,文章的具体内容,这些暂时不做。
那么这个需求的难题在哪里那?前后端交互不难,文章排版不难,后端获取博客首页的地址不难,难的是并发地处理分页文章数据。
首先一个人的文章是分页展示的,你首先需要获取总页数,然后并发去获取每页的文章数据。有可能会遇到服务器的封锁,也有很多异常需要捕获。
但问题都不算难,我也已经有思路了。

框架搭建,技术选型

因为对Nodejs了解比较多,之前也做过类似的功能,所有后端就用Nodejs,框架使用express,异步操作库使用async,因为前端只有一个页面,就不用前后端分离的形式了,直接html+jquery, 发送请求使用superagent 解析html使用 cheerio,

npm install -g express-generator
express --view=ejs blog-tool
cd blog-tool
npm i superagent cheerio async

  
 
  • 1
  • 2
  • 3
  • 4

开始编码

到了编码这一步,主要讲究的是思路,
因为文章是分页显示的,所有要知道文章的总页数,然后编写一个函数,获取一个http路径中的html源码,使用总页数控制循环调用函数,并将当前页码拼接到请求的url上。这样就能获取所有的文章了。
需要考虑的问题是,每次发送请求最好有一个时间间隔,另外就是循环调用异步函数后的回调函数的处理.所幸这些问题都能使用async得到解决。
核心代码如下

  async.times(totalPage, function(n, next) {
    getOnePageBlogLink(n, function(err, blogs) {
      next(err, blogs);
    });
  }, function(err, blogsArr) {
    const allBlogs = blogsArr.flat()
    console.log(allBlogs.length, 123)
    res.json({allBlogs})
  });

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

这部分是循环调用函数getOnePageBlogLink的核心代码,参数totalPage是博客的总页数。

函数 getOnePageBlogLink的内容是这样的,使用superagent获取htmlcheeriohtml进行解析,拿到需要的数据,文章标题,文章链接

var getOnePageBlogLink = function(pageIndex, callback) {
  pageIndex = pageIndex + 1
  superagent
    .get(`${userBlogLink}/article/list/${pageIndex}`)
    .set(setData)
    .then(res => {
      let blogHrefArr = []
      let $ = cheerio.load(res.text)
      let allEle = $(articleSelector)
      let len = allEle.length
      if (len > 0) {
        console.log(`获取到${len}条博客记录`)
        for (let i = 0; i < len; i++) {
          let name = allEle.eq(i).text()
          name = name.replace('原创', '')
          let blogItem = {
            name,
            href: allEle.eq(i).attr('href'),
          }
          blogHrefArr.push(blogItem)
        }
      }
      callback(null, blogHrefArr)
    })
    .catch(err => {
      callback(err, null)
    })
};

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

页面展示

展示的页面就比较简单了,使用bootstrap美化了一下,注意在express中,如果你的html是要直接访问就存放在public目录中,不能存放在views目录中,因为默认地express会将views中的当做模板,即ejs,或者pug等,需要编译并配置路由才能访问。而放到public中就不需要这么麻烦,知识访问。域名加文件名,不需要待public
html的完整源码

<!DOCTYPE html>
<html lang="zh-CN">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <!-- 上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! -->
    <title>Blog Tool</title>
    <link href="./lib/bootstrap/css/bootstrap.min.css" rel="stylesheet">
    <style type="text/css">
    .blog-item{
      display: inline-block;
      height: 100px;
      width: 200px;
      vertical-align: middle;
      border: 1px solid #ddd;
      padding: 5px;
      border-radius: 4px;
      margin-right: 5px;
    }
    .blog-item:hover{
      cursor: pointer;
      box-shadow: 0 5px 20px 0 rgba(176, 195, 211, 0.16);
    }
    .blog-item a{
      height: 100%;
      width: 100%;
      display: inline-block;
    }
    .blog-content{
      display: flex;
      flex-wrap: wrap;
      justify-content: space-around;
    }
    </style>
  </head>
  <body>
    <div class="container">
      <div class="row" style="margin-top: 30px;">

        <form class="form-horizontal">
          <div class="form-group">
            <label for="inputEmail3" class="col-sm-2 control-label">Blog URL</label>
            <div class="col-sm-10">
              <input type="text" class="form-control" id="userBlogLink" placeholder="https://fizzz.blog.csdn.net/">
            </div>
          </div>
          <div class="form-group">
            <label for="inputPassword3" class="col-sm-2 control-label">Total Page</label>
            <div class="col-sm-10">
              <input type="number" class="form-control" id="totalPage" placeholder="9">
            </div>
          </div>

          <div class="form-group">
            <div class="col-sm-offset-2 col-sm-10">
              <button type="button" class="btn btn-default" onclick="submitForm()">START</button>
            </div>
          </div>
        </form>

        <div class="blog-content" id="blog-content">

        </div>

      </div>
    </div>

    <!-- jQuery (Bootstrap 的所有 JavaScript 插件都依赖 jQuery,所以必须放在前边) -->
    <script src="https://cdn.jsdelivr.net/npm/jquery@1.12.4/dist/jquery.min.js"></script>
    <!-- 加载 Bootstrap 的所有 JavaScript 插件。你也可以根据需要只加载单个插件。 -->
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/js/bootstrap.min.js"></script>
    <script>

      function submitForm () {
        let userBlogLink = $("#userBlogLink").val()
        let totalPage = $("#totalPage").val()
        console.log(userBlogLink, totalPage)
        $.get('/blog/get-user-all-blogs',{userBlogLink, totalPage},function(data) {
          console.log(data)
          let allBlogs = data.allBlogs
          allBlogs.forEach(x => {
            let bolgItemHtml = []
            bolgItemHtml.push(`<p class="blog-item"><a href="${x.href}" target="_blank">${x.name}</a></p>`)
            $('#blog-content').append(bolgItemHtml.join(''))
          })
        })
      }

    </script>
  </body>
</html>

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92

运行之后会打印相关的日志

写在最后

这个程序稍微改进一下,目前软件的开发,只进行到这里,后续还会加上,文章的统计,报表功能. 稍微修改也可以做成备份博客的工具。

本文首发 https://www.ebaina.com/articles/140000005081?utm_source=homeindex&utm_medium=techarticle&utm_campaign=140000005081

文章来源: fizzz.blog.csdn.net,作者:拿我格子衫来,版权归原作者所有,如需转载,请联系作者。

原文链接:fizzz.blog.csdn.net/article/details/111029258

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。