博客原文备份小记——博客园

/博客园博文备份小记

 

   夏天呆在空调房里,看看书,撸撸代码,写写文章,还是蛮爽的。

   最近花时间写了个博客园博文备份脚本,简单又好玩,与大家分享下。

   之前有玩过一段时间的 node,几乎是一直在做爬虫,纯粹是因为好玩嘛,然后看到张大大的 这篇文章,感觉 fs 模块也是值得一撸的,就想找个 demo 试试手,马上就想到了      给博客园博文做备份。

   其实我本人一直有备份的好习惯,博客园博文备份的地址是 https://i.cnblogs.com/BlogBackup.aspx,但是备份结果是个 xml 的文件,这个用户体验就不好了吧,用过简书    的备份,down 下来的就是原始的 markdown 文件或者 html 文件(如果用的是富文本编辑器的话),从 xml 提取元素生成 md/html 文件,不正好来练手下 fs 模块嘛!

   fs 模块其实就是 node 的文件系统模块(FileSystem),提供了对于文件一系列的操作 API,比如创建文件啊,创建路径啊,遍历文件,修改文件名啊,等等,反正你能想到的    对于文件的操作,它都有,具体的 API 可以参考 官网,也可以看下 中文文档

   我们先分析下 xml 文件。

其实非常简单就能看出来,每一篇文章都在一个 <item> 标签中,里面有各种子元素,代表各种信息,比如 <title> 内包裹的就是文章 title,<link> 是文章链接,<description> 就是正文内容啦,我们的目标就是把正文内容提取出来,保存为 markdown 文件就 ok 啦!等等,我以前写的还有不少需保存为 html 格式的,这就尴尬了,还需要引入相应的 css 才能保证在本地打开样式不出错,所以还没开始用 markdown 写文章的童鞋,强烈建议现在就开始学习 markdown!

开始写代码啦。首先我们要读取 xml 文件,获取文件内容,我们用的是 fs 的 readFile API,回调中可以获取到读取的内容。对于读取到的 string,我们希望可以用类似 dom 选择器去选取,cheerio 又派上了用场。

fs.readFile(xmlSrc, {encoding: "utf-8"}, function(err, data) { var $ = cheerio.load(data); }); })

接下去我们遍历每一个 <item> 元素,然后提取其下的 <description> 元素中的内容,作为文章正文,我们把文章 title 当做文件名。

这个过程不复杂,但还是有几点需要注意下。

  • <description> 并不完全就是文章正文,还需要过滤 <!--[CDATA[ 和 ]]--> 两个子串,很好找,在首尾,一眼就看出来了
  • 因为我把文章标题当做了文件名,但是有些字符可以在标题中,但不能在文件名中(我是 windows 系统,不清楚别的系统是什么规则),用正则直接过滤了。

    // 文章标题
    var title = $(item).find("title").text(); // 过滤非法字符 title = title.replace(/(\/|\\|\:|\*|\?|\"|\<|\>|\|)/g, "");
  • 之前说了,有 markdown 和 html 两个类型的文件,都在 <description> 的标签内,看了下似乎没有别的判断方式,只能根据标签实体内容判断,简单写了个判断,对于我的文章貌似够用了。

    // 判断是 HTML 还是 markdown
    isHTML = (content.indexOf("style") !== -1 || content.indexOf("class") !== -1) && content.indexOf("![]") === -1;

    关于 html 格式的文件,如果要在本地正常打开,最好能备份相应的 css,但是由于对内容不造成影响,就没做这一步。

  • 关于文件的存储路径。这个可以自由发挥,简书的做法是把所有博文都备份在了一级目录下,但是由于我个人的文章可能比较多,我把文章按月来分了,即年份命名的文件夹为二级目录,比如有 2016,2015 以及 2014 三个二级目录(对,我写博客两年左右,跨了三年了),然后每个文件夹下又有具体月份,比如 1 月的文章放一个文件夹,二月的放一个,出于程序员的习惯,我把它们按照 0-11 编号了。如何知道文章发表的日期?<pubDate> 标签内的数据分析下就 ok 了。对于判断路径是否存在,我们可以用 fs.existsSync,而创建路径,可以用 fs.mkdirSync,这些 API 的使用都非常的简单,可以看文档。

最后还有一点要提的是,我把文章的图片也备份了,然后将正文中图片的 src 替换成了本地的地址,关于图片的下载,没有现成的 API,简单找了个函数,仅支持 HTTP 下的,对于博客园已经够用了。

// to download picture
function download(url, savePath) { var req = http.get(url, function(res){ var binImage = ''; res.setEncoding('binary'); res.on('data', function(chunk){ binImage += chunk; }); res.on('end', function(){ if (!binImage) { console.log('image data is null'); return null; } fs.writeFile(savePath, binImage, 'binary', function(err){ if (err) throw err; console.log('It\'s saved!'); // 文件被保存 }); }); }); }

备份完后目录结构大概是这样的:

cnblogs|
      --|2014
        --|9
          --|greasemonkey常见问题
            --|greasemonkey常见问题.html
          --|用php自动发邮件的简单实现 --|用php自动发邮件的简单实现.html --|img --|10 --|chrome扩展制作之hello world篇 --|chrome扩展制作之hello world篇.html --|img ... --|2015 ... --|2016 ...

详细的代码和使用方式可以参考 https://github.com/hanzichi/funny-node/tree/master/cnblogs-backup,有兴趣的也可以自己撸一个适合自己的。更深入的话,可以定时从 cnblogs 下载 xml 文件,定时备份,就更自动化了。

ps:fs 模块真是太实用了,之前维护这个 repo https://github.com/hanzichi/leetcode 的时候,每做一道题都要更新下 README,实在苦不堪言,现在直接用 fs 写了个 gererate.js,简直爽爆!

分类:  Node.js
 
好文要顶  关注我  收藏该文   
 
 

转载于:https://www.cnblogs.com/wanqi007/p/5744754.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值