解决Hexo博客批量上传的小问题:利用 Python 脚本提取 HTML 文件

Cover

一、前言

每次写完一篇文章后,我都要手动上传到我的博客空间服务器,虽然算不上麻烦,不过还是非常羡慕那些直接使用 Git Deploy 命令的朋友们,一键发布,方便快捷啊!

因为 Hexo 博客框架所生成页面都是静态 HTML 文件,所以当我更新博客的某一个功能或者添加一个小插件的时候,所有的页面都会更新,包括图片等文件的修改时间!所谓:“牵一发而动全身”,这个时候我就非常痛苦了,需要重新上传本月的所有文章、今年的所有文章、去年的所有文字……

所以,基于这个痛点,我早已在心里下定了决心,在某一天要亲手“解决它”!嗯,时机来了,最近有空闲时间的时候在自学 Python ,刚好可以尝试练习一下,利用 Python 脚本来提取需要更新的文件,然后复制到一个与源文件路径对应的临时文件夹中,最后批量上传到服务器覆盖即可,不得不说这句话是对的:

人生苦短,我(需要)用 Python !

另外,如果你还没有创建博客,推荐使用 Hexo 搭建;如果刚创建博客,还在搜寻可用插件的话,那么可以参考我之前的几篇文章:

二、正文

注意:本文仅适用于那些使用 Hexo 搭建博客,平时写的文章有大量图片,还需要自己手动上传服务器的朋友。其他同学就请随意啦! ?

问题所在

问题已经描述过了,比如之前我在自己的博客页面添加了一个日历云小插件,然后高兴地使用 hexo g 命令重新生成所有文章,接下来一顿崩溃:

  1. 我的文章比较多,网络不给力,上传所有文件到服务器非常耗时
  2. 直接覆盖全部文件会遇到断线重连的情况,导致服务器上某些文件“半途而废”
  3. 图片多而且不会发生变化,不需要把图片上传覆盖到服务器
  4. 如果选择手动提取 HTML 文件则非常耗时,因为文件夹“很有深度”

!文件夹深度

有点啰嗦,虽然我使用的 WinSCP 有选择覆盖“最新的文件”的功能,但是并没有什么卵用,我也没有在 Hexo 插件中找到相关解决方案的插件,所以只能自己动手了。

文件覆盖方式

解决思路

思路非常简单:只要把需要更新的类型的文件提取出来到一个临时文件夹,同时保持和源文件的文件夹结构相同,那么上传的时候只需要一次性覆盖最顶层文件夹就可以了!

一般来说,需要重新上传覆盖的文件都很小,是一些数据文件,比如: hmtl/json/xml/js 等。

所有代码

代码就不用说明了,非常简单,完全新手作品,主要使用 Python 的 shutil 模块就可以轻松解决文件提取和复制等问题。

import os
import shutil

def searchFile(src_dir, ext_filters, result_list):
    if not os.path.exists(src_dir) or not os.path.isdir(src_dir):
        print('None exits folder or not a directory at all, for:', src_dir, 'and will be ignored!')
        return
    for file in os.listdir(src_dir):
        file = os.path.join(src_dir, file)
        if os.path.isfile(file) and os.path.splitext(file)[1] in ext_filters:
            result_list.append(file)
        elif os.path.isdir(file):
            searchFile(file, ext_filters, result_list)

def getSearchedFiles(src_dir, ext_filters):
    results = []
    searchFile(src_dir, ext_filters, results)
    print('Find %d files in %s directory!' % (len(results), src_dir))
    return results

def copySingleFile(src_file, dst_dir):
    if not os.path.exists(src_file):
        print('No such source file')
        return
    src_dir = os.path.split(src_file)[0] if os.path.isfile(src_file) else src_file
    src_dir = os.path.relpath(src_dir)
    dst_dir = os.path.join(dst_dir, src_dir)
    dst_dir = dst_dir.replace('..\\', '')  # for test!
    if not os.path.exists(dst_dir):
        os.makedirs(dst_dir)
    shutil.copy2(src_file, dst_dir)

def createGeneratedFolder():
    current_path = os.path.abspath('.')
    # 临时文件夹,自行修改吧
    generate_path = os.path.join(current_path, 'temp')
    generate_path = os.path.join(generate_path, 'generated')
    if os.path.exists(generate_path):
        os.removedirs(generate_path)
        os.makedirs(generate_path)
    return generate_path

# 修改这里为你的文件夹路径
def getInputWorkDirectories():
    dirs = [] # 你的文件夹路径,绝对路径,可以不写
    use_default = input('Use default directories?(y/n):')
    if use_default not in ['n', 'no', 'NO', 'N']:
        return dirs
    path = input('Input the work directory(0 char to stop):')
    dirs = [path]
    while len(path) > 1:
        path = input('Input the work directory(0 char to stop):')
        dirs.append(path)
    return dirs

def startWork():
    gene = createGeneratedFolder()
    dirs = getInputWorkDirectories()
    if len(dirs) == 0:
        return
    extensions = getInputExtensions() # 方法已省略,返回扩展名数组
    for d in dirs:
        files = getSearchedFiles(d, extensions)
        for f in files:
            copySingleFile(f, gene)

if __name__ == '__main__':
    print('Start working......')
    startWork()
    print('Done!')

注:省略了一点点代码,可以直接到这里下载我写好的文件: copy_html.py ,最后代码中修改您的博客文件路径即可!

在绝对路径和相对路径上,我写的还有点问题,还请大家多多包涵与指正,谢谢! ?

三、总结

代码太简单了,不过还算解决了我的一个小小烦恼。当然,你完全可以使用其他语言实现,比如 Kotlin/C#/JavaScript 等等,在这里我再次感受到了 Python 的简洁与方便。嘿嘿。

如果有大神看到了这篇文章,希望能打造一个 Hexo 内部功能或者插件,类似用于重新生成指定文件类型的命令,就像: hexo rebuild -html,json,xml 。(嗯,这个命令是我乱写的,别被忽悠!)

谢谢大家的观赏,欢迎留言交流! ?

我的博客地址: http://liuqingwen.me ,欢迎关注我的微信公众号:
IT自学不成才

猜你喜欢

转载自blog.csdn.net/SpkingR/article/details/84989084