Python自动上传图片到博客园

一、前言


一直使用Typora记录笔记,虽然博客园有markdown编辑器,但是直接复制后其中的图片还需要一张一张的上传,弄图床的话,免费的感觉不稳定,收费的又怕被刷流量。

然后通过搜索,查看到了该博客python实现博客园自动上传图片 ,发现里面功能正好是自己需要的,自动将md文件内的图片上传到博客园中,并且将图片链接替换为博客园返回的网络地址,还会生成新的md文件。

但是将源码复制后,进行测试发现无法使用,通过查看源码后,排查出是正则表达式(34,35行)的问题,然后根据自己的需求进行修改后就可以使用了。

修改后的脚本,针对md图片链接,支持html和markdown语法,仅支持相对路径(如果是绝对路径的话需要自己修改正则表达式)。

目前修改后的脚本功能够自己使用了,虽然代码还有点乱,但是能用就行,麻烦的就是每次使用要在网页中抓取cookie后粘贴到源码使用。

二、使用方法


2.1 获取cookie并写入源码

打开博客园,调出开发者工具(F12),然后登入后通过网络查看请求包中的cookie

image-20230404193633448 image-20230404193952697

2.2 使用脚本生成新的md文件

在要上传图片的md文件目录处,右键后选择打开终端,输入python log.py,后根据提示输入文件路径即可。

image-20230404194201125 image-20230404195422765

2.3 其他

注意使用的时候不要开启代理服务。

blog

三、源码


import requests
import re
import sys
import argparse
#请首先设置自己的Cookie:打开博客园,登录以后,自己控制台抓包再复制到这里就好了
# Cookie的key为`.Cnblogs.AspNetCore.Cookies`,仅此一个就足够了
cookie = '写入自己的cookie'
newline = bytearray(b'\r\n')
'''
------WebKitFormBoundary0B5IAB61P3SBVPIR
Content-Disposition: form-data; name="imageFile"; filename="QQ图片20220528140941.jpg"
Content-Type: image/jpeg


'''
jpg = bytearray(b'\x2D\x2D\x2D\x2D\x2D\x2D\x57\x65\x62\x4B\x69\x74\x46\x6F\x72\x6D\x42\x6F\x75\x6E\x64\x61\x72\x79\x30\x42\x35\x49\x41\x42\x36\x31\x50\x33\x53\x42\x56\x50\x49\x52\x0D\x0A\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x44\x69\x73\x70\x6F\x73\x69\x74\x69\x6F\x6E\x3A\x20\x66\x6F\x72\x6D\x2D\x64\x61\x74\x61\x3B\x20\x6E\x61\x6D\x65\x3D\x22\x69\x6D\x61\x67\x65\x46\x69\x6C\x65\x22\x3B\x20\x66\x69\x6C\x65\x6E\x61\x6D\x65\x3D\x22\x51\x51\xE5\x9B\xBE\xE7\x89\x87\x32\x30\x32\x32\x30\x35\x32\x38\x31\x34\x30\x39\x34\x31\x2E\x6A\x70\x67\x22\x0D\x0A\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x54\x79\x70\x65\x3A\x20\x69\x6D\x61\x67\x65\x2F\x6A\x70\x65\x67\x0D\x0A\x0D\x0A')
png = bytearray(b'\x2D\x2D\x2D\x2D\x2D\x2D\x57\x65\x62\x4B\x69\x74\x46\x6F\x72\x6D\x42\x6F\x75\x6E\x64\x61\x72\x79\x30\x42\x35\x49\x41\x42\x36\x31\x50\x33\x53\x42\x56\x50\x49\x52\x0D\x0A\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x44\x69\x73\x70\x6F\x73\x69\x74\x69\x6F\x6E\x3A\x20\x66\x6F\x72\x6D\x2D\x64\x61\x74\x61\x3B\x20\x6E\x61\x6D\x65\x3D\x22\x69\x6D\x61\x67\x65\x46\x69\x6C\x65\x22\x3B\x20\x66\x69\x6C\x65\x6E\x61\x6D\x65\x3D\x22\x51\x51\xE5\x9B\xBE\xE7\x89\x87\x32\x30\x32\x32\x30\x35\x32\x38\x31\x34\x30\x39\x34\x31\x2E\x70\x6E\x67\x22\x0D\x0A\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x54\x79\x70\x65\x3A\x20\x69\x6D\x61\x67\x65\x2F\x70\x6E\x67\x0D\x0A\x0D\x0A')
bmp = bytearray(b'\x2D\x2D\x2D\x2D\x2D\x2D\x57\x65\x62\x4B\x69\x74\x46\x6F\x72\x6D\x42\x6F\x75\x6E\x64\x61\x72\x79\x30\x42\x35\x49\x41\x42\x36\x31\x50\x33\x53\x42\x56\x50\x49\x52\x0D\x0A\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x44\x69\x73\x70\x6F\x73\x69\x74\x69\x6F\x6E\x3A\x20\x66\x6F\x72\x6D\x2D\x64\x61\x74\x61\x3B\x20\x6E\x61\x6D\x65\x3D\x22\x69\x6D\x61\x67\x65\x46\x69\x6C\x65\x22\x3B\x20\x66\x69\x6C\x65\x6E\x61\x6D\x65\x3D\x22\x51\x51\xE5\x9B\xBE\xE7\x89\x87\x32\x30\x32\x32\x30\x35\x32\x38\x31\x34\x30\x39\x34\x31\x2E\x62\x6D\x70\x22\x0D\x0A\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x54\x79\x70\x65\x3A\x20\x69\x6D\x61\x67\x65\x2F\x62\x6D\x70\x0D\x0A\x0D\x0A')
gif = bytearray(b'\x2D\x2D\x2D\x2D\x2D\x2D\x57\x65\x62\x4B\x69\x74\x46\x6F\x72\x6D\x42\x6F\x75\x6E\x64\x61\x72\x79\x30\x42\x35\x49\x41\x42\x36\x31\x50\x33\x53\x42\x56\x50\x49\x52\x0D\x0A\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x44\x69\x73\x70\x6F\x73\x69\x74\x69\x6F\x6E\x3A\x20\x66\x6F\x72\x6D\x2D\x64\x61\x74\x61\x3B\x20\x6E\x61\x6D\x65\x3D\x22\x69\x6D\x61\x67\x65\x46\x69\x6C\x65\x22\x3B\x20\x66\x69\x6C\x65\x6E\x61\x6D\x65\x3D\x22\x51\x51\xE5\x9B\xBE\xE7\x89\x87\x32\x30\x32\x32\x30\x35\x32\x38\x31\x34\x30\x39\x34\x31\x2E\x67\x69\x66\x22\x0D\x0A\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x54\x79\x70\x65\x3A\x20\x69\x6D\x61\x67\x65\x2F\x67\x69\x66\x0D\x0A\x0D\x0A')

#主流的就支持这几种了,如有需要,自己添加上面类型的字节数组,以及添加filemap,还要下面的pattern2处
filemap = {".jpg":jpg,".jpeg":jpg,".png":png,".bmp":bmp,".gif":gif}
'''
Content-Disposition: form-data; name="host"

www.cnblogs.com
------WebKitFormBoundary0B5IAB61P3SBVPIR
Content-Disposition: form-data; name="uploadType"

Paste
------WebKitFormBoundary0B5IAB61P3SBVPIR--
'''
end = bytearray(b'\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x44\x69\x73\x70\x6F\x73\x69\x74\x69\x6F\x6E\x3A\x20\x66\x6F\x72\x6D\x2D\x64\x61\x74\x61\x3B\x20\x6E\x61\x6D\x65\x3D\x22\x68\x6F\x73\x74\x22\x0D\x0A\x0D\x0A\x77\x77\x77\x2E\x63\x6E\x62\x6C\x6F\x67\x73\x2E\x63\x6F\x6D\x0D\x0A\x2D\x2D\x2D\x2D\x2D\x2D\x57\x65\x62\x4B\x69\x74\x46\x6F\x72\x6D\x42\x6F\x75\x6E\x64\x61\x72\x79\x30\x42\x35\x49\x41\x42\x36\x31\x50\x33\x53\x42\x56\x50\x49\x52\x0D\x0A\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x44\x69\x73\x70\x6F\x73\x69\x74\x69\x6F\x6E\x3A\x20\x66\x6F\x72\x6D\x2D\x64\x61\x74\x61\x3B\x20\x6E\x61\x6D\x65\x3D\x22\x75\x70\x6C\x6F\x61\x64\x54\x79\x70\x65\x22\x0D\x0A\x0D\x0A\x50\x61\x73\x74\x65\x0D\x0A\x2D\x2D\x2D\x2D\x2D\x2D\x57\x65\x62\x4B\x69\x74\x46\x6F\x72\x6D\x42\x6F\x75\x6E\x64\x61\x72\x79\x30\x42\x35\x49\x41\x42\x36\x31\x50\x33\x53\x42\x56\x50\x49\x52\x2D\x2D\x0D\x0A')
pattern1 = re.compile("(<img).*?(/>)|!\[image-.*].*") #检测是不是图片
pattern2 = re.compile(r"(\./).*?(png|jpeg|jpg|pjpg|gif|bmp)")  #提取本地图片链接,
#读取文件不应该失败的,返回图片原始数据
def getData(path):
        file = open(path,"rb")
        data = file.read()
        return data
# ![image-20230331125315475](./test.assets/image-20230331125315475.png)
#把本地图片上传到博客园并返回生成的链接
def postPicture(path):
    url = 'https://upload.cnblogs.com/imageuploader/CorsUpload'
    header = {
        'sec-ch-ua': '" Not A;Brand";v="99", "Chromium";v="101", "Microsoft Edge";v="101"',
        'Content-Type': 'multipart/form-data; boundary=----WebKitFormBoundary0B5IAB61P3SBVPIR',
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.74 Safari/537.36 Edg/99.0.1150.46',
        'Referer': 'https://i.cnblogs.com/',
        'Origin':'https://i.cnblogs.com',
        'Host':'upload.cnblogs.com',
        'Sec-Fetch-Site':'same-site',
        'Sec-Fetch-Mode':'cors',
        'Sec-Fetch-Dest':'empty',
        'Accept':'application/json, text/plain, */*',
        'X-XSRF-TOKEN':'CfDJ8M-opqJn5c1MsCC_BxLIULn9r64eLYNLwVMXkMrkLJ93e_4yvVvrduOZrBxJciy6XVmh9Xr0_huw7Fb8NAwVEvtPt9otjJvAjm7kVU82p4_a3mez4ngUc8MZUBHIbMjZro0bggr6EA-d7puUYmCdMIeZi4aC5OKQIoHwcJC6I4d59h1Jew3BzOnlOKJWa06p9g',
        'Cookie':cookie
    }
    data = bytearray(getData(path))
    data += newline
    type = path[path.rindex("."):]
    total = filemap[type] + data + end  #构造post数据,只有图片内容需要改动,其余都是固定的
    web = requests.post(url,data=total, headers=header)
    js = web.json()
    if js['success']==True:
        print("[INFO] 博客园返回地址:",js['message'])
        return js['message']
    else:
        print("[Error]",js['message'])
    return path

#解析md文件,把本地图片链接替换为生成链接,并生成替换链接后的md文件
def parseMd(path):
    print("[INFO] 获取md文件中的图片链接(仅支持相对路径),路径 --->"+path)
    file = open(path,"r",encoding="utf-8")
    new_path = path.replace(".md","_cnblogs.md")
    newfile = open(new_path,"w",encoding="utf-8")
    for line in file.readlines():
        print("[INFO] 确认是否为图片 ---> "+line)
        if pattern1.search(line) == None:
            print("[INFO] 匹配失败")
            str = ''
        else:
            str = pattern1.search(line).group()

        if len(str)>0:
            str = pattern2.search(str).group()
            print("[INFO] 正则获取图片相对路径! 图片相对路径 ---> "+str)
            if len(str)>0:
                newstr = postPicture(str)
                line = line.replace(str,newstr)
        newfile.write(line)
    file.close()
    newfile.close()



def main():
    print("请输入md文件路径:")
    str = input()
    parseMd(str)

main()
posted @ 2023-04-04 20:03  滴滴打怪  阅读(174)  评论(0)    收藏  举报