自动将md文档中的图片上传到简书
2019-08-12 本文已影响0人
tristan_lee
最近在写东西时发现一些文档里图片较多(自己一般都是用md写东西),每次上传时经常要花时间手动去拉图上传,简书不能在拷贝md文档时直接自动上传所有图片,非常麻烦;感觉简书这方面做得也很差,完全没体验可言。还是自己动手写个小工具吧,花了点时间研究下简书的图片上传接口,写个python脚本匹配文档中的图片位置,自动上传后并替换图片链接,以后可以省点事。
工具
Charles - 用来抓包分析图片上传数据报文流程(只在分析图片上传的HTTP包流程时用)
Chrome插件EditThisCookie - 用来导出简书的cookies(导出格式为name=value pairs)
流程与代码
-
用Chrome浏览器登录简书账号,然后导出jianshu的cookies,保存为文件(导出格式为name=value pairs),文件名为cookies.txt并与脚本文件保存在同一目录,用于上传图片时的会话验证。简书的cookies有效期好像是一月,时间够用了。
-
运行脚本,替换完后会输出新文件output.md
replace_md.py xxx.md
-
源码:
#!/usr/bin/env python3 import requests import json import os import sys import datetime import re import imghdr import _locale _locale._getdefaultlocale = (lambda *args: ['zh_CN', 'utf8']) cookie_file = 'cookies.txt' upload_url = 'https://upload.qiniup.com/' # get cookie from cookie file def getCookie(path): try: with open(path, 'r') as f: content = f.readlines() for line in content: cook = line.split(';') if len(cook) > 1: break cookies = '' for str in cook: if str.find('token') != -1: cookies += str+';' if str.find('uid') != -1: cookies += str+';' if str.find('sensorsdata') != -1: cookies += str+';' return cookies except Exception as error: print(error) def uploadImage(cook_path, filepath, name='img'): cookStr = getCookie(cook_path) #print(cookStr) filename = os.path.basename(filepath) fname,suffix=os.path.splitext(filepath) if suffix == '': suffix = imghdr.what(filepath) filename = fname+'.'+suffix token_url = 'https://www.jianshu.com/upload_images/token.json?filename={}'.format(filename) headers = { 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36', 'Cookie': cookStr, } response = requests.get(token_url, headers=headers) response.encoding = response.apparent_encoding token_key = json.loads(response.text) if 'token' not in token_key: return None with open(filepath, 'rb') as file: files = { 'file': (filename, file), 'token': (None, token_key['token']), 'key': (None, token_key['key']), } response = requests.post(upload_url, headers=headers, files=files) response.encoding = response.apparent_encoding img_url = json.loads(response.text)['url'] img_md = ''.format(text=name, img_url=img_url) return img_md def outputFile(path): try: with open(path, 'r') as fd, open("output.md", "w") as fd1: tmpPath = '__tmp__' content = fd.readlines() for line in content: # match http link image obj = re.search( r'!\[(.*)\]\((http.+)\)', line) if obj: name = obj.group(1) filePath = obj.group(2) with open(tmpPath, 'wb') as tmpFd: ir = requests.get(filePath) tmpFd.write(ir.content) newline = uploadImage(cookie_file, tmpPath, name) if newline is None: print('Err: ', 'uploadImage() error!') else: print('Ok: ', 'uploadImage() ok!') line = newline fd1.write(line) continue # match local file image obj = re.search( r'!\[(.*)\]\((.+)\)', line) if obj: name = obj.group(1) filePath = obj.group(2) newline = uploadImage(cookie_file, filePath, name) if newline is None: print('Err: ', 'uploadImage() error!') else: print('Ok: ', 'uploadImage() ok!') line = newline fd1.write(line) if os.path.exists(tmpPath): os.remove(tmpPath) return None except Exception as error: print('err:', error) def main(path): if os.path.exists(path): outputFile(path) return True else: print("File path %s not exist!" % (path)) return False if __name__ == '__main__': if len(sys.argv) <= 1: print("Usage error: replace_md.py %path") sys.exit(-1) else: main(sys.argv[1]) sys.exit(0)
基本流程:
- 使用正则匹配出md文档中的图片位置
- 根据图片位置的链接
- 如果是本地图片地址,直接上传,返回图片链接
- 如果是网络图片链接,先下载再上传,返回图片链接
- 用返回的图片链接替换md文档中原来的图片位置