nodejs 读取博客园自己博客列表 生成全部标题列表

需求

自己的博文有823篇了,但是不能在一页里面显示,本来想通过 MetaWeblog 读取,后来发现失败了。
没办法,自己写个脚本读取吧。

之前MetaWeblog 读取 失败的文章:https://www.cnblogs.com/pengchenggang/p/16593890.html

原理

装一个axios,get读取一个页面,这样就获得了html,再通过正则 提取出标题和链接,存在数组里面。

经过递归,刷一遍列表分页。为了保证顺序,所以要第一页读取完成后,再进行第二也的加载。

上截图

上代码

// cnblogs-node.js
const axios = require("axios")
const fs = require('fs')
const pageTotal = 22
let currPage = 1
let dataArr = []

getPageContent(1) // 从第1页到22页 递归调用

function getPageContent (page) {
  axios.get('https://www.cnblogs.com/pengchenggang/default.html?page='+page).then(res => {
    // console.info('res.data', res.data)
    const content = res.data
    const mainStartPosition = '<!--end: header 头部 -->'
    const mainEndPosition = '<!--end: main -->'
    let pos1 = 0, pos2 = 0
    pos1 = content.indexOf(mainStartPosition) + mainStartPosition.length
    pos2 = content.indexOf(mainEndPosition) + mainEndPosition.length
    console.info('pos1', pos1)
    console.info('pos2', pos2)

    const listContent = content.substring(pos1, pos2)
    // console.info('listContent', listContent)

    const reg = new RegExp(/<a class=\"postTitle2[\s\S]*?<\/a>/, "g")
    // const reg = new RegExp(/<a\b[^>]+\bhref="([^"]*)"[^>]*>([\s\S]*?)</a>/, "g");

    if (reg.test(listContent)) {
      // 找到内容了
      console.info('匹配上拉')
      const ret = getRegExec(reg, listContent)
      const ret1 = formatRet(ret) // 格式化所需要的对象
      // console.log("ret1", ret1)
      console.log("第"+ page + "页 读取完成")
      dataArr.push(...ret1)
      if (page === pageTotal) {
        fs.writeFile('data.json', JSON.stringify(dataArr), function () {
          console.info('data.json 写入完成!')
        })
        const renderHtml = getRenderHtml(dataArr)
        fs.writeFile('html.html', renderHtml, function () {
          console.info('html.html 写入完成!')
        })
      } else {
        getPageContent(page + 1)
      }
    } else {
      console.info('没有匹配上')
    }
  })
}

function getRenderHtml(arr) {
  return arr.map(item => {
    return '<a href="'+item.link+'" target="_blank">'+item.title+'</a>'
  }).join('\n')
}
function formatRet (arr) {
  let ret = []
  arr.map(item => {
    ret.push(getLinkAndTitle(item))
  })
  return ret
}

function getLinkAndTitle (str) {
  // const mock = '<a class="postTitle2 vertical-middle" href="https://www.cnblogs.com/pengchenggang/p/16601242.html">\n' +
  //   '    <span>\n' +
  //   '        软件发布时 生成发布日志文件 单点登录 getGitInfo.bat\n' +
  //   '    </span>\n' +
  //   '    \n' +
  //   '</a>'

  const reg2 = new RegExp(/href="([\s\S]*?)">[\s\S]*?<span>([\s\S]*?)<\/span>/, "g")
  const m2 = reg2.exec(str)
  // console.info('m2', m2)
  const link = m2[1]
  const title = m2[2].replace(/\\n/, 'g').trim()
  // console.info('link title', link, title)
  return {
    title,
    link
  }
}

function getRegExec (reg, txt) {
  var m
  var ret = []
  do {
    m = reg.exec(txt)
    // console.info('m', m)
    if (m) {
      ret.push(m[0])
    }
  } while (m)
  return ret
}

package.json

{
  "name": "cnblogs-nodejs-script",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "run": "node cnblogs-node.js"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "axios": "^0.27.2"
  }
}

all cnblogsByPengchenggang 样式显示模板

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>all cnblogsByPengchenggang</title>
  <style>
    a {
      font-size: 14px;
      /* display: block; */
      /* margin: 5px 20px; */
      color: #666666;
    }

    a:hover {
      color: #333333;
      font-size: 14px;
      background-color: #f2f2f2;
    }

    .list {
      counter-reset: main;
      /* width: 800px; */
      margin: 0 auto;
    }

    a::before {
      counter-increment: main;
      content: counter(main);
      padding-right: 10px;
    }
  </style>
</head>

<body class="">
  <div class="list">
    $TemplateListSlot
  </div>
</body>

</html>

复盘

这里主要3个知识点

  1. 读取数据 用axios
  2. 解析数据 用正则
  3. 存储数据 用nodejs
posted @ 2022-08-22 09:37  彭成刚  阅读(33)  评论(0编辑  收藏  举报