前言
最近在做emoji表情,在windows环境预览效果不太理想,也缺少很多字体图标的显示,为了让各种环境显示一致,决定用svg图片代替字体图标。让设计去搞这些资源,有一千多个图标,比较费力。于是决定自己写个脚本去抓这些资源。notion
有这些资源,开始去抓。
调研准备工作
之前在做emoji的时候,有Unicode Id
,notion中的资源名称也是用Unicode id
做文件名。根据id关联,我们就可以直接开始了。
emoji.json 文件
{
"id": "u1f600",
"name": "嘿嘿",
"font": "😀",
"keyword": "😀^嘿嘿^笑^^嘿嘿|笑脸|脸"
}
....
node脚本准备
俗话说,工欲善其事必先利其器,在写脚本之前,我们先搞几个操作文件的工具方法,服务于正式脚本的使用。
// 读文件
const readFile = async (path) => {
return new Promise((resolve, reject) => {
fs.readFile(path, 'utf8', (err, data) => {
if (err) {
console.log(err);
reject(err);
return;
}
resolve(data);
})
})
}
// 写文件
const writeFile = async (path, data) => {
return new Promise((resolve, reject) => {
fs.writeFile(path, data, { flag: 'w' }, (err) => {
if (err) {
console.log(err);
reject(err);
return;
}
resolve(true);
})
})
}
/**
* 获取网络文件到本地
* @param {*} webUrl
* @param {*} path
*/
const downloadHttpFile = async (webUrl, folderPath) => {
return new Promise((resolve, reject) => {
const fileName = path.basename(webUrl);
let stream = fs.createWriteStream(path.join(folderPath, fileName));
request(webUrl).pipe(stream).on("close", function (err) {
if (err) {
console.log(err);
reject(err);
return;
}
resolve(true)
console.log("文件[" + fileName + "]下载完毕");
});
})
}
正式脚本
- 定义路径变量
// emoji 路径
const emojiPath = path.join(__dirname, '../assets/emoji.json');
// notion 路径
const emojiSvgBase = 'https://notion-emojis.s3-us-west-2.amazonaws.com/prod/svg-twitter'; // 1f604.svg
// svg图片下载文件夹
const downloadFolder = path.join(__dirname, 'images');
- 读取文件抓取,写文件
// 获取文件并下载
const getEmojiSvgFile = async (id) => {
const fileName = id + '.svg';
const webUrl = `${emojiSvgBase}/${fileName}`;
const exist = fs.existsSync(downloadFolder);
if (!exist) {
fs.mkdirSync(downloadFolder);
}
return await downloadHttpFile(webUrl, downloadFolder);
}
// 从notion抓取所有的图片
const grabImages = async () => {
const data = await readFile(emojiPath)
const emojiJson = JSON.parse(data.toString());
for (const first of emojiJson) {
for (const second of first.children) {
const id = handleUnicodeId(second.id);
// 串行抓取
await getEmojiSvgFile(id)
}
}
}
// 开始抓取
grabImages();
- 设置启动命令
在package.json中添加命令
"scripts": {
"grab": "node ./src/index.js"
},
4.运行命令
npm run grab
大家看上边的脚本,可以发现我们用了asyc
和await
, 串行去下载资源。有兴趣的小伙伴可以尝试改下,看看怎么改成并行
去下载资源,还可以控制并发
的数量
,面试中经常会问到。
结束语
代码已上传github,有需要可自行查看。小伙伴们可以试下并发请求,评论区见~。