// 定义常量
const url = "https://www.luogu.com.cn";
console.log("Warning: When the program is running, don't log out your luogu account...");
const uid = "{}"
let restCount = 0;
// 获取博客内容的函数
async function fetchBlogContent(bid) {
// 全局计数器加 1
restCount += 1;
if (restCount % 10 === 0) {
console.log("Please wait for 5 seconds...");
// 等待 10 秒
await new Promise(resolve => setTimeout(resolve, 5000));
}
// 发送请求获取博客详情
const response = await fetch(`${url}/api/blog/detail/${bid}`);
const result = await response.json();
// 处理响应状态
if (result.status === 200) {
const data = result.data;
return {
source: `${url}/blog/_post/${bid}`,
content: data.Content,
identifier: data.Identifier,
postTime: data.PostTime,
title: data.Title,
type: data.Type
};
} else {
console.error(`Error: Cannot catch blog ${bid}, result: ${result}`);
return {};
}
}
files = []
// 保存博客内容的函数
async function saveBlogContent(bid) {
const result = await fetchBlogContent(bid);
if (Object.keys(result).length === 0) {
return;
}
// 格式化时间
const postTime = new Date(result.postTime * 1000).toISOString().replace('T', ' ').substring(0, 19);
const titleLine = `# ${result.title}\n`;
const metaLine = `posted on ${postTime} | under ${result.type} | [source](${result.source})\n\n`;
const contentLine = `${result.content}\n`;
files.push({
title: `${result.identifier}.md`,
content: titleLine + metaLine + contentLine
})
console.log(`Save blog ${bid} successfully...`);
}
// 获取博客列表的函数
async function getBlogLists(uid) {
const response = await fetch(`${url}/api/blog/userBlogs`);
const result = (await response.json()).blogs;
const lists = [];
const pageNumber = Math.ceil(result.count / result.perPage);
for (let i = 1; i <= pageNumber; i++) {
const pageResponse = await fetch(`${url}/api/blog/userBlogs?page=${i}`);
const pageResult = (await pageResponse.json()).blogs;
for (const blog of pageResult.result) {
lists.push(blog.id);
}
}
return lists;
}
// 主函数,用于获取博客列表并保存博客内容
async function main() {
console.log(`Now start fetching blogs of user ${uid}.`);
const blogIds = await getBlogLists(uid);
console.log(`${blogIds.length} blogs in total.`)
for (const bid of blogIds) {
await saveBlogContent(bid);
}
console.log(files)
// 将 files 转为 json 格式,提供给用户下载
const jsonData = JSON.stringify(files, null, 2);
const blob = new Blob([jsonData], { type: 'application/json' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = 'blogs.json';
a.click();
URL.revokeObjectURL(url);
console.log(`Blogs of user ${uid} have already saved.`);
console.log("Thank you for using my tool. Author: Luogu @yukimianyan.");
}
// 调用主函数
main().catch(error => console.error('An error occurred:', error));
复制代码到控制台即可使用,由于技术受限,最终只能下载一个 .json 文件,文件中有所有博客的标题和内容。代码由豆包生成。
配套使用的以下代码,将下载的 .json 文件转化为若干文件。以下代码为 python 代码,需要预先 pip install json
(也可能不需要),然后需要手动修改最后三行的文件路径。同样地,代码由豆包生成。
import json
import os
def json_to_files(json_file_path, output_directory):
# 检查输出目录是否存在,如果不存在则创建
if not os.path.exists(output_directory):
os.makedirs(output_directory)
try:
# 打开 JSON 文件并加载数据
with open(json_file_path, 'r', encoding='utf-8') as f:
data = json.load(f)
# 遍历 JSON 数组中的每个对象
for item in data:
title = item.get('title')
content = item.get('content')
if title and content:
# 构建文件的完整路径
file_path = os.path.join(output_directory, title)
# 打开文件并写入内容
with open(file_path, 'w', encoding='utf-8') as output_file:
output_file.write(content)
print(f"文件 {title} 已成功创建。")
else:
print("跳过无效的对象,缺少 'title' 或 'content' 属性。")
except FileNotFoundError:
print(f"未找到 JSON 文件: {json_file_path}")
except json.JSONDecodeError:
print(f"JSON 文件格式错误: {json_file_path}")
# 示例用法
if __name__ == "__main__":
json_file_path = "blogs.json" # 替换为实际的 JSON 文件路径
output_directory = "./blogs" # 替换为实际的输出目录
json_to_files(json_file_path, output_directory)
标签:const,title,JavaScript,博客,json,result,file,path,洛谷
From: https://www.cnblogs.com/caijianhong/p/18706277