有时看到一些博客写的不错,贴个连接当然愉快,但过段时间总会发现要么博客中的图片挂了,要么直接是博客挂了。因此出于保护原博主的宝贵心血不至于白流(手动狗头),进行了一番折腾(固然,请注明转载并标注出处)。html
本次折腾的思路是:利用正则表达式批量导出原博的全部图床连接,批量下载后经过调用Tencent cos的API进行批量上传,最后批量获取腾讯云中的图片连接并以此替换掉原博客中的图床连接。python
做为正则的入门,刘江的博客介绍的很是系统,以后再结合文档等的函数说明基本就够用了。git
须要注意的是,re.match只匹配字符串的开始,若是字符串开始不符合正则表达式,则匹配失败,函数返回None;而re.search/re.findall匹配整个字符串,直到找到一个匹配。re.sub并不会直接替换目标字符串,通常须要借助赋值语句。github
本次匹配虽然无涉编码正则表达式
在python3中,str字符串是以Unicode进行编码的。算法
具体的说,当咱们实例化一个字符串时,如
list ='the winter is coming'
。python将默认该字符串为str类型,同时将经过Unicode映射表将该字符串映射为对应的Unicode编码。全部的字符串相关的操做都将经过操做对应的Unicode编码实现。express但当咱们要储存这个字符串时,因为Unicode并非具体的实现方式(即存储编码方式),咱们须要指定具体的编码方式,如python默认的utf-8。api
bytes其实应该理解为存储在系统中的具体的字节流对象,而不存在什么单独的bytes类型字符串。若是咱们要解读一个bytes对象,咱们须要知道对应的编码方式(不是像Unicode这样的编码规范,而是像utf-8这样的具体编码方式)。服务器
使咱们迷惑的是这么一种声明方式:函数
>>> bytes([1,2,3,4,5,6,7,8,9]) >>> bytes("python", 'ascii') # 字符串,编码
然而,这两种方式都是以默认或指定的方式将字符串编码为字节流。
参考:
python3字符串编码总结-str(unicode)_bytes
这里使用腾讯云的对象存储,是由于接口调用相对简单,且拥有50G的免费空间,通常我的博客使用是够用了。若是想用其余云盘服务也是能够的。
https://cloud.tencent.com/product/cos
肯定后点击基础配置
- 将空间名称(bucket)“test-1257994648”粘贴保存。
- 所属区域(region)的“ap-chengdu”粘贴保存,后面调用API时会用到。
- 编辑防盗链设置,在白名单中添加你的域名(博客连接)。
使用调用腾讯云API时须要签名,云API密钥用于生成签名。
而后在打开的页面中点击“新建秘钥”,将得到的SecretId和SecretKey妥善保存。
安装 SDK 有三种安装方式:pip 安装、手动安装和离线安装。
pip install -U cos-python-sdk-v5
从 XML Python SDK 下载源码,经过 setup 手动安装,执行如下命令。
python setup.py install
# 在有外网的机器下运行以下命令
mkdir cos-python-sdk-packages
pip download cos-python-sdk-v5 -d cos-python-sdk-packages
tar -czvf cos-python-sdk-packages.tar.gz cos-python-sdk-packages
# 将安装包拷贝到没有外网的机器后运行以下命令
# 请确保两台机器的 python 版本保持一致,不然会出现安装失败的状况
tar -xzvf cos-python-sdk-packages.tar.gz
pip install cos-python-sdk-v5 --no-index -f cos-python-sdk-packages
完成上面的步骤后,调用API就很简单了。查查文档,修改便可。
不过最新版的SDK中未贴出建立、删除目录等操做(历史版本下的SDK对此却提供了支持)。经过摸索,发现多个函数方法中都包含的一个关键参数的说明是这样的:
解决之道就在此中。
# 下面是调用前的重复性工做
## 1. 设置用户配置, 包括 secretId,secretKey 以及 Region
## -*- coding=utf-8
from qcloud_cos import CosConfig
from qcloud_cos import CosS3Client
import sys
import logging
logging.basicConfig(level=logging.INFO, stream=sys.stdout)
secret_id = 'xxxxxxxx' # 替换为用户的 secretId
secret_key = 'xxxxxxx' # 替换为用户的 secretKey
region = 'ap-beijing-1' # 替换为用户的 Region
token = None # 使用临时密钥须要传入 Token,默认为空,可不填
scheme = 'https' # 指定使用 http/https 协议来访问 COS,默认为 https,可不填
config = CosConfig(Region=region, SecretId=secret_id, SecretKey=secret_key, Token=token, Scheme=scheme)
## 2. 获取客户端对象
client = CosS3Client(config)
## 参照下文的描述。或者参照 Demo 程序,详见 https://github.com/tencentyun/cos-python-sdk-v5/blob/master/qcloud_cos/demo.py
# 下面是API调用的实例,你能够根据需求从文档找到须要的方法。
file_name = 'test.txt'
with open('D://test.txt', 'rb') as fp:
response = client.put_object(
Bucket='test04-123456789',
Body=fp,
Key=file_name,
StorageClass='STANDARD',
ContentType='text/html; charset=utf-8'
)
print(response['ETag'])
第一步是匹配出原博中全部的图片连接(固然,其余连接也能够)。
此次我转载的是CSDN上的一篇博客,CSDN的图片连接是这样的:[](图片地址2)
对应的正则表达式为:\\[!\\[.*?\\]\\(.*?\\)\\]\\((.*?)\\)
注意:
将所得的图片连接下载到本地,为下一步上传作准备。
调用API实现。
本应该经过API批量生成分享连接,但实践发现,腾讯的分享连接接口有个expire参数,用于控制连接有效时间,默认300秒,很是不便。后来经过观察发现,存储桶中的文件直链结构很是简单,直接由桶的域名加上文件名就构成了。若是你的连接访问不了,请检查桶的读权限是否为公有。
这个简单,经过正则匹配就能够了。
最后贴上代码,有须要的能够本身修改使用。
# -*- coding=utf-8
import re
import os
import urllib
from qcloud_cos import CosConfig
from qcloud_cos import CosS3Client
import sys
import logging
# 将本地md中的图片连接提取出并储存于urllist中,
blog_url = 'C:\\Users\\zzp\OneDrive - stu.xjtu.edu.cn\\文档\\typora\\草稿.md'
blog_name = re.match(u'(.*)\.md$',os.path.basename(blog_url)).group(1)
pic_type = []
try:
f = open(blog_url, encoding='utf-8')
lines = f.readlines()
except FileNotFoundError as e:
print("夭寿啦,文件没找到!")
f.close()
urllist =[]
compile_eurl = re.compile('\[!\[.*?\]\(.*?\)\]\((.*?)\)')
for line in lines:
try:
urllist.extend(compile_eurl.findall(line))
except AttributeError as e:
print("error")
# 获取图片后缀,以备后面命名使用
pic_type = re.match('.*?\.([a-zA-Z]{3}$)', urllist[0]).group(1)
# 批量下载连接对应图片到本地
for i in range(len(urllist)):
try:
urllib.request.urlretrieve(urllist[i], "D:/临时/"+blog_name+'_'+str(i) + '.'+pic_type)
except:
print('夭寿啦,下载失败啦!')
print('完成图片下载')
## 利用腾讯提供的cos存储官网sdk进行批量上传
logging.basicConfig(level=logging.INFO, stream=sys.stdout)
## 设置用户属性, 包括secret_id, secret_key, region
secret_id = 'AKERXXXXXXXXXXXXXXXXXXXXXXXX' # 替换为你的secret_id
secret_key = 'TmxxXXXXXXXXXXXXXXXXXXXXXXXXXXXX' # 替换为你的的secret_key
region = 'ap-chengdu' # 替换为你的region/服务器地域编号
token = None # 使用临时秘钥须要传入Token,默认为空,可不填
config = CosConfig(Region=region, SecretId=secret_id, SecretKey=secret_key, Token=token) # 获取配置对象
client = CosS3Client(config)
# 文件流 简单上传
for i in range(len(urllist)):
with open("D:/临时/"+blog_name+'_'+str(i) + '.'+pic_type, 'rb') as fp:
response = client.put_object(
Bucket='test-1257994648', # 咱们上面保存的空间名
Body=fp,
Key=blog_name + '_' + str(i) + '.' + pic_type,
StorageClass='STANDARD',
ContentType='text/html; charset=utf-8'
)
print('完成图片上传')
# 更换博客图片连接
i = len(urllist)
compile_url = re.compile(u'\[!\[.*?\]\(.*?\)\]\(.*?\)')
for x in range(len(lines)):
while compile_url.findall(lines[x]):
lines[x] = re.sub(compile_url, ') + '.' + pic_type+')', lines[x], count=1)
i = i+1
print(lines)
# 写入博客
with open(blog_url, encoding='utf-8', mode='w') as f:
f.writelines(lines)