1. 程式人生 > 實用技巧 >[Python] Hexo博文圖片上傳圖床並自動替換連結的Python指令碼

[Python] Hexo博文圖片上傳圖床並自動替換連結的Python指令碼

前兩天搗鼓了一下Github page + Hexo搭建部落格,發現本地編寫的Markdown博文釋出以後圖片連結還是用的本地路徑,導致圖片沒法正常顯示。網上搜了一下,解決辦法大都是安裝外掛、手動上傳圖床再插入連結、用線上Markdown編輯器等。感覺不是很方便,於是寫了一個Python指令碼在文章釋出以前自動把文章裡的圖片上傳到SM.MS圖床或者騰訊雲物件儲存並替換文章內的圖片連結。

以下是程式碼

import re
import requests
import json
from qcloud_cos import CosConfig
from qcloud_cos import CosS3Client
import sys
#import logging
import argparse
import os
import time
import shutil
from urllib import parse

def get_artical_path(art_tittle):
        '''
        合成文章路徑
        '''
        try:
                dir_path = os.getcwd()
                #如果是在部落格根目錄放置指令碼,請修改testdir\_posts路徑為source\_posts或其他放置文章的目錄。
                article_path = os.path.join(dir_path,r"source\_posts",art_tittle)
                return article_path
                print(article_path)
        except BaseException as err:
                print("error in get_artical_path\n{}".format(err))

def change_pic_path(article_path,upld_method):  
        '''
        article_path: 文章的本地路徑
        upld_method: 上傳方法,sm.ms,騰訊cos,本地(github)。
        '''
        print("please wait a moment")
        try:
                with open (article_path,'r',encoding = 'utf-8') as md:
                        article_content = md.read()
                        pic_block = re.findall(r'\!.*?\)',article_content)  #獲取新增圖片的Markdown文字
                        if upld_method == "smms":
                                for i in range(len(pic_block)):
                                        pic_origin_url = re.findall(r'\((.*?)\)',pic_block[i]) #獲取插入圖片時圖片的位置
                                        pic_new_url = smms(pic_origin_url[0])
                                        print("pic_new_url is {}".format(pic_new_url))
                                        article_content = article_content.replace(pic_origin_url[0],pic_new_url)
                        elif upld_method == "tx":
                                for i in range(len(pic_block)):
                                        pic_origin_url = re.findall(r'\((.*?)\)',pic_block[i]) #獲取插入圖片時圖片的位置
                                        #print("pic_origin_url is {}".format(pic_origin_url))
                                        pic_new_url = tx(pic_origin_url[0])
                                        print("pic_new_url is {}".format(pic_new_url))
                                        article_content = article_content.replace(pic_origin_url[0],pic_new_url)
                        elif upld_method == "local":
                                for i in range(len(pic_block)):
                                        pic_origin_url = re.findall(r'\((.*?)\)',pic_block[i]) #獲取插入圖片時圖片的位置
                                        pic_new_url = local(pic_origin_url[0])
                                        print("pic_new_url is {}".format(pic_new_url))
                                        article_content = article_content.replace(pic_origin_url[0],pic_new_url)
                        else:
                                print("part of get_pic_path error")

                with open (article_path,'w',encoding = 'utf-8') as md:
                        md.write(article_content)
                print("job done")

        except BaseException as err:
                print("error in change_pic_path\n{}".format(err))

#上傳至SM.MS
def smms(pic_origin_url):
        try:
                smms_url = 'https://sm.ms/api/upload'
                #file_path = r"C:\Users\Root\AppData\Roaming\Typora\typora-user-images\1542107269017.png"   #for test
                data = requests.post(
                        smms_url,
                        files={'smfile':open(pic_origin_url,'rb'),
                        'format':'json'}
                )
                pic_new_url = json.loads(data.text)
                cloud_path = pic_new_url['data']['url'] 
                return(cloud_path)

        except BaseException as err:
                print("error in smms\n{}".format(err))

def tx(pic_origin_url):
        '''
        上傳至騰訊雲
        '''
        try:
                secret_id = ''          # 替換為使用者的 secretId
                secret_key = ''          # 替換為使用者的 secretKey
                region = ''         # 替換為使用者的 Region
                Bucket = '' #替換為使用者的Bucket
                token = None                                # 使用臨時金鑰需要傳入 Token,預設為空,可不填
                scheme = 'https'                        # 指定使用 http/https 協議來訪問 COS,預設為 https,可不填
                config = CosConfig(Region=region, SecretId=secret_id, SecretKey=secret_key, Token=token, Scheme=scheme)
                client = CosS3Client(config)

                pic_basename = os.path.basename(pic_origin_url)                #獲取檔名及字尾
                time_for_dir = time.strftime("%Y-%m-%d")                #獲取當前日期用於命名資料夾

                #預設上傳後建立一個以當前日期命名的資料夾,如果不需要,註釋掉這一行用下一行。
                cloud_path = time_for_dir + r'/' + pic_basename                
                #cloud_path = pic_basename
                key = cloud_path
        # 2. 獲取客戶端物件
                with open(pic_origin_url, 'rb') as fp:
                        response = client.put_object(
                                Bucket=Bucket,
                                Body=fp,
                                Key=key,
                        #StorageClass='STANDARD',
                        #ContentType='text/html; 
                        #charset='utf-8'
                        )
                cloud_path = client._conf.uri(bucket=Bucket, path=key)
                return cloud_path
        except BaseException as err:
                print("error in tx\n{}".format(err))

if __name__ == '__main__':

        parser = argparse.ArgumentParser()
        subparsers = parser.add_subparsers(help="commands", dest="command")

        smms_parser = subparsers.add_parser("smms",help="use smms")
        smms_parser.add_argument("art_tittle",help="input filename")

        tx_parser = subparsers.add_parser("tx",help="use tx cos")
        tx_parser.add_argument("art_tittle",help="input filename")

        local_parser = subparsers.add_parser("local",help="use local")
        local_parser.add_argument("art_tittle",help="input filename")

        args = parser.parse_args()

if args.command == "smms":
        article_path = get_artical_path(args.art_tittle)
        change_pic_path(article_path,'smms')

if args.command == "tx":
        print ('use tx,file name is {}'.format(args.art_tittle))
        article_path = get_artical_path(args.art_tittle)
        change_pic_path(article_path,'tx')

使用方法

將指令碼放在部落格本地根目錄,當前目錄下命令列輸入python uploadpic.py <上傳方式> <文章名.md>
貌似通常情況下部落格文章都是放在source/_posts資料夾的,所以指令碼自動查詢的是source/_posts目錄,如果你的文章是放在其他目錄中,請手動修改程式碼中的目錄。
上傳方式:
smms - SM.MS
ts - 騰訊雲COS,需要填寫相應的secret_id、secret_key、region、Bucket 及安裝騰訊雲cos-python-sdk-v5

最後

本人乃初學程式設計的業餘選手,在程式碼書寫、程式設計思路等各方面還請大佬們多多指點。

可能是搜尋力度不夠,真的沒發現有啥好的插入圖片方法,如果有更好方法的也請說一下。
測試較少,可能出現各種奇怪的問題。我也不知道是怎麼回事。
Github地址:https://github.com/lixint/img_upload_for_Markdown