使用python进行实现。 在以游客身份通过爬虫方式和登录后使用官方api两种情况下调用了imgbb的api。但最终因为上传速度原因使用的是阿里图床。imgbb两种面向探索过程。如果单纯想查看调用阿里api请查看ali图床部分
实现了图床图片url和相对路径url的互换。
1. imgbb
1.1. 游客身份
1.1.1. 上传图片请求分析
- 请求体中一共有五个参数,多次上传图片后分析可得
- source:二进制文件,就是图片数据
- type: file,固定值
- action: upload,固定值
- timestamp: 时间戳,在请求时通过python可以获得。
int(time.time())
- auth_token:也就是token,用于验证,需要进行获取
1.1.2. token获取
在全部文件中搜索token,若未发现token的值,刷新页面重新搜索
token应该从服务器获取的,如果打开开发者工具太晚可能无法捕捉到之前资源
可以发现auth_token的值。位于首页页面。通过正则表达式可以提取
token = re.findall(r"PF.obj.config.auth_token=\"(\w*)\"", html_str)[0]
1.1.3. 响应分析
搜索上传图片后跳转页面显示的连接,可以发现与响应的json数据中的该条相同
通过解析json字符串即可获得
1.1.4. 代码
def img_to_url(self, path=""):
""" 将img上传到图床并返回URL。
"""
print("正在上传图片-----%s",path)
file_name = ""
# 获取token
if(self.token == None):
self.get_token()
# 获得文件名
if path.find("/") != -1:
file_name = path.split("/")[-1:][0]
else:
file_name = path.split("\\")[-1:][0]
# 设置请求体参数
data = {
"type": "file",
"action": "upload",
"timestamp": int(time.time()),
"auth_token": self.__class__.token
}
# 设置上传文件
file = {
"source": (file_name, open(path, "rb"), "image/jpeg"),
}
# 进行请求
response = requests.post(
self.__class__.upload_url, headers=self.__class__.headers, files=file, data=data)
# 解析json
json_o = json.loads(response.content.decode("utf-8"))
# 返回路径
return json_o["image"]["display_url"]
1.2. 官方api
1.2.1. 分析
在imgbb进行注册后,点击左上角关于,进入官方api文档
- 参数:
- key:注册后可以在上方生成。必选
- image:base64编码后的图片数据
- name:图片名称,可选
- expiraion:图片描述,可选
- 响应json数据结构api文档下方已给出
1.2.2. 代码调用
def img_to_url_api(self,path):
""" 通过api接口上传到图床并返回url """
print("正在上传图片-----%s",path)
# 获得文件名
file_name = ""
if path.find("/") != -1:
file_name = path.split("/")[-1:][0]
else:
file_name = path.split("\\")[-1:][0]
with open(path,"rb") as file:
# 设置请求体
data = {
"key":self.__class__.key,
"name":file_name,
"image":base64.b64encode(file.read())
}
# 请求响应
response = requests.post( self.__class__.api_url, data = data)
# 解析json
json_o = json.loads(response.content.decode("utf-8"))
return json_o["data"]["image"]["url"]
1.2.3. 问题
在第一次访问图片有时会发生链接跳转,导致嵌入到md中后图片无法正常显示
fidder抓包后可以发现两次请求完全相同,但结果不同。未发现解决方式。
2. ali图床
2.1. api文档
官方未提供api,此处使用第三方提供api api文档
接口地址中有两个api接口,一个cn,一个us,根据需求选择
2.2. 代码调用
api_url = "https://cn1.api.wfblog.net/ali.pic.php"
def img_to_url_api(self,path):
""" 通过api接口上传到图床并返回url """
print("正在上传图片-----%s" % path)
with open(path,"rb") as file_:
file = {
"file":file_
}
response = requests.post(self.__class__.api_url,files = file)
json_o = json.loads(response.content.decode("utf-8"))
return json_o["data"]["url"]
3. url和path互相转换
在每次获得url地址后,都将path和url存储到json文件mapper.json中。不断更新mapper.json
通过正则获取md文件中的图片路径,并进行替换
- 转换为url路径
def update_md_file(self,path,json_dict): print("***开始更新文件***") url_or_path_list = None # 打开md文件 with open(path, "r+", encoding="utf-8") as md_file: text = md_file.read() # 获得所有图片路径 url_or_path_list = re.findall(r"!\[.*\]\((.*)\)", text) # 获得本地图片格式的路径 path_list = [i for i in url_or_path_list if i.startswith("..")] if(len(path_list)==0): print(" 无需替换更新") return print(" 正在更新文件") # 读取mapper.json中文件内容进行替换 for i in path_list: text = text.replace(i,json_dict[i]) print(" >>>>替换图片%s--->%s" % (i,json_dict[i])) # 重新写入 md_file.seek(0) md_file.truncate() md_file.write(text) print("***更新文件完成***")
- 转换为path路径
def a_file_to_path(self, path): print("***开始更新文件%s***" % path) # 此处读取mapper.json文件 if self.__class__.json_dict == None: with open("./mapping.json", "r") as json_file: self.__class__.json_dict = json.load(json_file) json_dict = self.__class__.json_dict url_or_path_list = None # 打开md文件 with open(path, "r+", encoding="utf-8") as md_file: text = md_file.read() # 获得所有图片路径 url_or_path_list = re.findall(r"!\[.*\]\((.*)\)", text) url_list = [i for i in url_or_path_list if i.startswith("http")] if(len(url_list) == 0): print(" 无需替换更新") return print(" 正在更新文件") # 将url替换为path for i in url_list: j = list(json_dict.keys())[list(json_dict.values()).index(i)] text = text.replace(i,j) print(" >>>>>替换图片%s--->%s" % (i,j)) # 重新写入 md_file.seek(0) md_file.truncate() md_file.write(text) print("---该文件完成---")