前言
上一篇中,搭建好了hexo next主题的博客,将cxxn中的所有博客导出为md文档后再全部上传到hexo站内,但是有一个很大的问题:hexo本地图片无法显示,需要安装插件,然后以非md外链的格式插入图片,这使用起来相当不便且不通用,因此放弃插入本地图片的方案。导出的md中的图片外链有的是csdn站内的,有的是github仓库里的,为了保证md中的图片能在各平台都正常显示,了解到七牛云免费提供10G OSS对象存储空间,因此,本篇记录一下将md中的图片迁移至七牛云云床的过程
注册七牛云
注册
注册后完成实名认证,可免费领取10G OSS空间。实名认证审核需要1个小时左右
假设你已经完成注册和实名,点击如下链接,免费领取空间: 领取10G OSS空间
创建OSS bucket
创建好bucket后,可以上传一下文件测试
获取图片上传至七牛云图床
这里写了一个python脚本,开10个线程处理md文档,逻辑是这样的:
1.扫描md文档,获取到其中的图片url
2.下载url将图片保存至本地
3.将本地的图片上传至七牛云
4.将md文档中的图片url替换成对应的七牛云外链url
七牛云OSS Python SDK地址: OSS Python SDK
代码:
import re
import requests
import os
from qiniu import Auth, put_file
from concurrent.futures import ThreadPoolExecutor
# 获取md文件中的图片链接,保存为文件,上传至七牛并返回七牛外链地址
def get_pic_url(filename):
url_map = {}
with open(filename, 'r',) as f:
content = f.read()
img_patten = r'!\[.*?\]\((.*?)\)|<img.*?src=[\'\"](.*?)[\'\"].*?>'
matches = list(re.compile(img_patten).findall(content))
if len(matches) > 0:
for url in matches:
url = url[0]
# 优快云图片直链有3种样式,真坑:
# 这一种文件名太长,直接这样命名上传到七牛云之后,有时外链链接无法加载.
# https://imgconvert.csdnimg.cn/aHR0cDovL2ltZy5ibG9nLmNzZG4ubmV0LzIwMTcxMTE2MTQ1MjIxNTky,
# 下面两种要去除后面的参数
# https://img-blog.csdnimg.cn/20181206193427845.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3l3cTkzNQ==,size_16,color_FFFFFF,t_70
# https://img-blog.youkuaiyun.com/20180626193940302?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3l3cTkzNQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70
print("图片原url:", url)
try:
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML,'
' like Gecko) Chrome/55.0.2883.87 Safari/537.36'
}
if "csdn" in url:
pic_name = url.split('csdnimg.cn/')[-1]
# pic_name = "{}/{}".format(pic_path, url.split('csdnimg.cn/')[-1])
pic_name = pic_name.split('youkuaiyun.com/')[-1]
pic_name = pic_name.split('?')[0]
# csdn部分直链链接里没有格式,加个图片尾缀
if not pic_name.endswith('.jpg') and not pic_name.endswith('.png'):
pic_name = pic_name + '.jpg'
elif "github" in url:
# 保存github图片,github直链的链接为文件链接加参数:?raw=true,例如:
# https://github.com/yinwenqin/kubeSourceCodeNote/blob/master/scheduler/image/p2/schedule.jpg?raw=true
pic_name = url.split('/')[-1]
url += "?raw=true"
else:
# 别的来源的图片链接如有不同,请自行按对应格式修改
pic_name = url.split('/')[-1]
response = requests.get(url, headers=headers).content
pic_name_len = len(pic_name)
# 名字太长截取一半
if pic_name_len > 40:
pic_name = pic_name[int(pic_name_len/2):]
pic_name = "{}/{}".format(pic_path, pic_name)
print(pic_name)
with open(pic_name, 'wb') as f2:
f2.write(response)
new_pic_url = pic_upload(pic_name)
url_map[url] = new_pic_url
except Exception as e:
print("文件:", filename, "url处理失败:", url, e)
return {}
print(url_map)
return url_map
# 获取所有的md文件
def list_file(files, path):
# 取出指定路径下的所有文件,包含所有子目录里的文件
items = os.listdir(path)
for i in items:
i_path = os.path.join(path, i)
if os.path.isdir(i_path):
list_file(i_path, files)
else:
if i_path.endswith(".md"):
files.append(i_path)
return files
# pic上传七牛云图床,获取图片在图床中的链接,替换md文档
def pic_upload(file):
try:
# 换成自己的认证及相关信息
endpoint = "http://xxxxxxxxx.bkt.clouddn.com"
access_key = "xxxxxxxxxxxx"
secret_key = "xxxxxxxxxxxx"
bucket_name = 'xxxxxxxxx'
key = os.path.basename(file)
q = Auth(access_key, secret_key)
token = q.upload_token(bucket_name, key, 3600)
put_file(token, key, file)
# 上传后得到的图片外链示例: http://pwh8f9az4.bkt.clouddn.com/AlgSchedule.jpg
new_url = endpoint + '/' + os.path.basename(file)
# print('new url', new_url)
return new_url
except Exception as e:
print('upload image to QiNiu oss failed:', file, e)
return ""
# 替换md文件中的旧链接
def modify_md(filename, url_map):
try:
with open(filename, "r") as f:
content = f.read()
for url, new_pic_url in url_map.items():
with open(filename, "w") as f:
content = content.replace(url, new_pic_url)
f.write(content)
except Exception as e:
print(filename, '文件修改失败:', e)
def run(file):
# {old_url: new_url}
url_map = get_pic_url(file)
if len(url_map.keys()) > 0:
modify_md(file, url_map)
def main(path):
# 获取所有的md文件
files = list_file([], path)
if len(files) > 0:
th_pool = ThreadPoolExecutor(20)
for file in files:
th_pool.submit(run, file)
th_pool.shutdown(wait=True)
else:
print("no markdown found, exit")
if __name__ == "__main__":
md_path = "./md/"
pic_path = "../pic"
if not os.path.exists(pic_path):
os.makedirs(pic_path)
main(md_path)
运行完成后,将替换后的md放入username.github.io/source/_posts
内,push到仓库中,浏览器打开hexo blog可以看到,所有图片都可以正常显示
图床工具PicGo
markdown中插入图片一直以来都不太方便,即使是使用外链,一般也需要如下繁琐步骤:
1.保存图片
2.上传图片至云床
3.复制云床外链
4.md中插入外链
于是诞生了图床工具的需求,mac中有一款非常好用的图床上传工具iPic,支持七牛云但收费48/年,找了很久最后都打算自己撸工具的时候,发现了一款免费开源的神器PicGo,而且难能可贵的是win/linux/mac平台都能支持,试用了一番,同样相当强大。
mac一键安装:
brew cask install picgo
其余平台参考项目地址: PicGo
PicGo支持拖拽式上传图片,也支持直接使用快捷键将粘贴板中的图片上传至云床,上传完成后,自动将得到的外链地址写入系统粘贴板内,在md中直接粘贴即可显示图片。
上面繁琐的步骤,简化为了:截图至粘贴板 -> 快捷键上传至图床(cmd + ctrl + u) -> 粘贴使用。使用起来行云流水,一气呵成,非常之爽,爱了爱了,良心工具,墙裂推荐!