需求
自己的博文有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个知识点
- 读取数据 用axios
- 解析数据 用正则
- 存储数据 用nodejs