Files
blog/tools/download-juejin-images.js
geek 61bff7beac style: 配置站点副标题/Logo/头像并整理图片资源
- 启用首页副标题(打字机效果)
- 修复 nav.logo 被 theme_config 空值覆盖导致不显示的问题
- 头像改为 /images/core.jpg
- 重做 logo:去白底并圆形内部填白
- 新增 Markdown 使用指南,整理文章图片到对应目录
2026-07-08 23:07:24 +08:00

77 lines
2.5 KiB
JavaScript

// 下载 Markdown 中的掘金外链图片,按文章归类到 source/images/<文章名>/,并替换链接为站内路径
const fs = require('fs');
const path = require('path');
const https = require('https');
const http = require('http');
const ROOT = 'c:/Users/Administrator/Desktop/新建文件夹/blog';
const MD = path.join(ROOT, 'source/_posts/Git使用教学.md');
// 以文章文件名(去掉扩展名)作为图片子文件夹名,便于按文章管理
const POST = path.basename(MD, path.extname(MD));
const OUT = path.join(ROOT, 'source/images', POST);
function download(url) {
return new Promise((resolve, reject) => {
const lib = url.startsWith('https') ? https : http;
const req = lib.get(url, { headers: { 'User-Agent': 'Mozilla/5.0' } }, (res) => {
// 跟随重定向
if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {
res.resume();
return download(new URL(res.headers.location, url).href).then(resolve, reject);
}
if (res.statusCode !== 200) {
res.resume();
return reject(new Error('HTTP ' + res.statusCode));
}
const chunks = [];
res.on('data', (c) => chunks.push(c));
res.on('end', () => resolve(Buffer.concat(chunks)));
});
req.on('error', reject);
req.setTimeout(30000, () => req.destroy(new Error('timeout')));
});
}
(async () => {
fs.mkdirSync(OUT, { recursive: true });
let content = fs.readFileSync(MD, 'utf8');
const re = /!\[[^\]]*\]\((https:\/\/p3-juejin\.byteimg\.com\/[^)\s]+)\)/g;
const map = {}; // url -> /images/<POST>/xxx.webp
let m;
const tasks = [];
while ((m = re.exec(content)) !== null) {
const url = m[1];
if (map[url]) continue;
const seg = url.split('/').pop();
const hash = seg.split('~')[0];
if (!hash) {
console.log('跳过(无法解析文件名): ' + url);
continue;
}
const file = hash + '.webp';
map[url] = '/images/' + POST + '/' + file;
tasks.push(
download(url)
.then((buf) => {
fs.writeFileSync(path.join(OUT, file), buf);
console.log('[OK] ' + file + ' <- ' + url);
})
.catch((e) => {
console.log('[FAIL] ' + url + ' -> ' + e.message);
delete map[url];
})
);
}
await Promise.all(tasks);
for (const url in map) {
content = content.split(url).join(map[url]);
}
fs.writeFileSync(MD, content); // UTF-8 无 BOM
console.log('\n完成:处理 ' + Object.keys(map).length + ' 张图片');
})();