自动将md文档中的图片上传到简书

最近在写东西时发现一些文档里图片较多(自己一般都是用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 = '//www.greatytc.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 = '![{text}]({img_url})'.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文档中原来的图片位置
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。