将微信公众号文章图像链接改为七牛云图床链接
import os
import re
import requests
from qiniu import Auth, put_file, etag
from urllib.parse import urlparse
import tempfile
import hashlib
import shutil
import time
class QiniuMarkdownImageMigrator:
def __init__(self, access_key, secret_key, bucket_name, domain):
self.access_key = access_key
self.secret_key = secret_key
self.bucket_name = bucket_name
self.domain = domain
self.q = Auth(access_key, secret_key)
def extract_image_urls(self, markdown_content):
# 匹配markdown中的图片链接 
pattern = r'!\[.*?\]\((http[s]?://[^\)]+)\)'
return re.findall(pattern, markdown_content)
def download_image(self, url, temp_dir):
try:
response = requests.get(url, stream=True)
if response.status_code == 200:
# 根据URL生成文件名
parsed = urlparse(url)
filename = os.path.basename(parsed.path)
# 如果没有文件名或没有后缀名
if not filename or '.' not in filename:
# 从Content-Type获取图片类型
content_type = response.headers.get('Content-Type', 'image/jpeg')
ext = {
'image/jpeg': '.jpg',
'image/png': '.png',
'image/gif': '.gif',
'image/webp': '.webp'
}.get(content_type, '.jpg')
# 使用URL哈希+时间戳作为唯一文件名
filename = f"{hashlib.md5(url.encode()).hexdigest()}_{int(time.time())}{ext}"
# 确保文件名有后缀
elif '.' not in filename:
filename += '.jpg'
filepath = os.path.join(temp_dir, filename)
with open(filepath, 'wb') as f:
response.raw.decode_content = True
shutil.copyfileobj(response.raw, f)
return filepath
except Exception as e:
print(f"下载图片失败 {url}: {e}")
return None
def upload_to_qiniu(self, local_file):
try:
# 上传后的文件名
key = os.path.basename(local_file)
token = self.q.upload_token(self.bucket_name, key, 3600)
ret, info = put_file(token, key, local_file)
if ret and ret.get('key') == key and ret.get('hash') == etag(local_file):
return f"{self.domain}/{key}"
except Exception as e:
print(f"上传图片到七牛云失败 {local_file}: {e}")
return None
def process_markdown_file(self, input_path, output_path=None):
if not output_path:
output_path = input_path
with open(input_path, 'r', encoding='utf-8') as f:
content = f.read()
image_urls = self.extract_image_urls(content)
if not image_urls:
print(f"{input_path} 中没有找到网络图片")
return False
with tempfile.TemporaryDirectory() as temp_dir:
for url in image_urls:
print(f"正在处理图片: {url}")
local_path = self.download_image(url, temp_dir)
if not local_path:
continue
new_url = self.upload_to_qiniu(local_path)
if new_url:
content = content.replace(url, new_url)
with open(output_path, 'w', encoding='utf-8') as f:
f.write(content)
return True
if __name__ == "__main__":
# 七牛云配置
access_key = "xxx"
secret_key = "xxx"
bucket_name = "xxx"
domain = "https://xxx.com"
# 创建迁移器实例
migrator = QiniuMarkdownImageMigrator(access_key, secret_key, bucket_name, domain)
# 获取当前目录下的所有.md文件
import glob
md_files = glob.glob("*.md")
for md_file in md_files:
# 在原文件基础上修改
print(f"正在处理文件: {md_file}")
migrator.process_markdown_file(md_file)
print(f"完成处理文件: {md_file}")
.qiniu_pythonsdk_hostscache.json
{"http:cGbklYyiISnV60JPcduCIzrTS_Rb-4PdVWzRVyeC:yunhui": {"upHosts": ["http://up.qiniu.com", "http://upload.qiniu.com", "-H up.qiniu.com http://115.231.29.10"], "ioHosts": ["http://iovip.qbox.me"], "deadline": 1743646787}}