CSDN 自动上传图片并优化Markdown的图片显示

文章目录

    • 完整代码
    • 一、上传资源
    • 二、替换 MD 中的引用文件为在线链接
    • 参考

完整代码

完整代码由两个文件组成,upload.pymain.py,放在同一目录下运行 main.py 就好!

# upload.py
import requests  


class UploadPic:  
    def __init__(self, cookie):  
        self.cookie = cookie  
  
        # 解析  
        self.file_path = ''  
        self.img_type = ''  
  
        # 两个请求体  
        self.upload_data = {}  
        self.csdn_data = {}  
        self.output_url = ''  
  
    def _get_file(self, file_path):  
        with open(file_path, mode='rb') as f:  
            binary_data = f.read()  
        return binary_data  
  
    def _upload_request(self):  
        headers = {  
            'accept': '*/*',  
            'accept-language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6',  
            'content-type': 'application/json',  
            'cookie': self.cookie,  
            'origin': 'https://editor.csdn.net',  
            'priority': 'u=1, i',  
            'referer': 'https://editor.csdn.net/',  
            'sec-ch-ua': '"Not/A)Brand";v="8", "Chromium";v="126", "Microsoft Edge";v="126"',  
            'sec-ch-ua-mobile': '?0',  
            'sec-ch-ua-platform': '"Windows"',  
            'sec-fetch-dest': 'empty',  
            'sec-fetch-mode': 'cors',  
            'sec-fetch-site': 'same-site',  
            'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36 Edg/126.0.0.0',  
        }  
  
        params = {  
            'type': 'blog',  
            'rtype': 'markdown',  
            'x-image-template': '',  
            'x-image-app': 'direct_blog',  
            'x-image-dir': 'direct',  
            'x-image-suffix': self.img_type,  
        }  
  
        url = 'https://imgservice.csdn.net/direct/v1.0/image/upload'  
  
        response = requests.get(url, params=params, headers=headers)  
        try:  
            self.upload_data = response.json()  
        except Exception as e:  
            return e  
  
    def _csdn_request(self):  
        headers = {  
            'Accept': 'application/json, text/javascript, */*; q=0.01',  
            'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6',  
            'Connection': 'keep-alive',  
            'Origin': 'https://editor.csdn.net',  
            'Referer': 'https://editor.csdn.net/',  
            'Sec-Fetch-Dest': 'empty',  
            'Sec-Fetch-Mode': 'cors',  
            'Sec-Fetch-Site': 'cross-site',  
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36 Edg/126.0.0.0',  
            'sec-ch-ua': '"Not/A)Brand";v="8", "Chromium";v="126", "Microsoft Edge";v="126"',  
            'sec-ch-ua-mobile': '?0',  
            'sec-ch-ua-platform': '"Windows"',  
        }  
  
        files = {  
            'key': (None, self.upload_data['data']['filePath']),  
            'policy': (None, self.upload_data['data']['policy']),  
            'OSSAccessKeyId': (None, self.upload_data['data']['accessId']),  
            'success_action_status': (None, '200'),  
            'signature': (None, self.upload_data['data']['signature']),  
            'callback': (None, self.upload_data['data']['callbackUrl']),  
            'file': (f'image.{self.img_type}', self._get_file(self.file_path), f'image/{self.img_type}'),  
        }  
  
        url = 'https://csdn-img-blog.oss-cn-beijing.aliyuncs.com/'  
  
        response = requests.post(url, headers=headers, files=files)  
        try:  
            self.csdn_data = response.json()  
            self.output_url = self.csdn_data['data']['imageUrl']  
        except Exception as e:  
            return e  
  
    def upload_image(self, file_path):  
        self.file_path = file_path  
        self.img_type = self.file_path.split('.')[-1]  
  
        exception_1 = self._upload_request()  
        assert exception_1 is None, exception_1  
        exception_2 = self._csdn_request()  
        assert exception_2 is None, exception_2  
  
        return self.output_url  
  
  
if __name__ == '__main__':  
    cookie = '' # 输入你的cookie  
    upload = UploadPic(cookie)  
    output_url = upload.upload_image('')  #输入你需要上传的文件位置
    print(output_url)
# main.py
import os  
import re  
from pathlib import Path  
from rich.progress import track  
from upload import UploadPic  


class CSDNTransform:  
    def __init__(self, upload:UploadPic, file_path, walk_path='C:/Users/Administrator/Documents/Obsidian Vault/'):  
        self.upload = upload  
        self.file_path = file_path  
        self.walk_path = walk_path  
  
        self.markdown_text = ''  
        self.image_lst = []  
        self.posterior_image_lst = []  
        self.image_2_url_dic = {}  
  
    def _get_markdown_text(self):  
        with open(self.file_path, mode='r', encoding='utf-8') as f:  
            markdown_text = f.read()  
        self.markdown_text = markdown_text  
  
    def _process_markdown_text(self):  
        image_lst = re.findall(r'(!\[\[.*]])', self.markdown_text)  
        posterior_image_lst = [item[3:-2] for item in image_lst]  
  
        self.image_lst = image_lst  
        self.posterior_image_lst = posterior_image_lst  
  
    def _get_target_image_path(self, target_path):  
        for root, floders, files in os.walk(self.walk_path):  
            for file in files:  
                if file == target_path:  
                    return str(Path(root) / file)  
  
    def _get_the_url_of_image(self, image_path):  
        image_url = self.upload.upload_image(image_path)  
        return image_url  
  
    def get_the_urls(self):  
        self._get_markdown_text()  
        self._process_markdown_text()  
  
        not_exist_image_index = []  
  
        for ix, (origin_image, target_path) in track(enumerate(zip(self.image_lst, self.posterior_image_lst))):  
            image_path = self._get_target_image_path(target_path)  
            if image_path is not None:  
                image_url = self._get_the_url_of_image(image_path)  
                self.image_2_url_dic[origin_image] = image_url  
            else:  
                not_exist_image_index.append(ix)  
  
        # 清楚掉需要删除的index  
        num = 0  
        for ix in not_exist_image_index:  
            del self.image_lst[ix-num]  
            del self.posterior_image_lst[ix-num]  
            num += 1  
  
    def _the_transform_data_from(self, image_url):  
        data_form = f"""\n<div align=center><img src="{image_url}"></div>\n"""  
        return data_form  
  
    def _save_markdown_text(self, output_file='markdown_processed.txt'):  
        with open(output_file, mode='w', encoding='utf-8') as f:  
            f.write(self.markdown_text)  
  
    def get_transform(self):  
        self.get_the_urls()  
  
        # Judge the length  
        assert len(self.image_lst) == len(self.image_2_url_dic), f"上传成功{len(self.image_2_url_dic)}张图片,总共有{len(self.image_lst)}张图片"  
  
        for origin_image, image_url in self.image_2_url_dic.items():  
            self.markdown_text = self.markdown_text.replace(origin_image, self._the_transform_data_from(image_url))  
  
        self._save_markdown_text()


if __name__ == '__main__':  
    cookie = ''  # 输入你的cookie
    file_path = ''  # 输入你要转换的markdown文件地址
    upload = UploadPic(cookie)  
    transform = CSDNTransform(upload, file_path)  
    markdown_text = transform.get_transform()

	# 修改后的 Markdown 在当前目录的 markdown_processed.txt 文件中

一、上传资源

首先我们解析 CSDN 上传请求,这里随便上传一张图片,观察请求;

请求由三部分组成,分别是:1. 获取存储位置和签名验证信息;2. 利用签名等验证信息上传文件;3. 获取文件信息并显示;

仔细观察两个请求,upload 请求是 GET ,csdn 请求是 POST,其结果很明显 csdn 请求是主体,仔细观察 csdn 的参数,可以所有参数都可以利用 upload 的返回结果得到;

那么接下来我们开始构造 upload 请求

import requests

headers = {
    'accept': '*/*',
    'accept-language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6',
    'content-type': 'application/json',
    'cookie': '', # 输入自己的cookies
    'origin': 'https://editor.csdn.net',
    'priority': 'u=1, i',
    'referer': 'https://editor.csdn.net/',
    'sec-ch-ua': '"Not/A)Brand";v="8", "Chromium";v="126", "Microsoft Edge";v="126"',
    'sec-ch-ua-mobile': '?0',
    'sec-ch-ua-platform': '"Windows"',
    'sec-fetch-dest': 'empty',
    'sec-fetch-mode': 'cors',
    'sec-fetch-site': 'same-site',
    'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36 Edg/126.0.0.0',
}

params = {
    'type': 'blog',
    'rtype': 'markdown',
    'x-image-template': '',
    'x-image-app': 'direct_blog',
    'x-image-dir': 'direct',
    'x-image-suffix': 'png',
}

url = 'https://imgservice.csdn.net/direct/v1.0/image/upload'
response = requests.get(url, params=params, headers=headers)

# 获得数据
upload_data = response.json()

得到 json 内容如下,通过比较该内容下 expire 和 time 库下的 time.time() * 1000,再根据英文名可以推断,expire 表示的是上传文件这一请求的失效时间,即 csdn 请求的最晚成功时间;

{'code': 200,
 'data': {'accessId': 'LTAI5tK31AXMAqwzaX1wn4hH',
          'callbackUrl': 'eyJjYWxsYmFja0JvZHlUeXBlIjoiYXBwbGljYXRpb24vanNvbiIsImNhbGxiYWNrVXJsIjoiaHR0cHM6Ly9pbWdzZXJ2aWNlLmNzZG4ubmV0L2RpcmVjdC92MS4wL2ltYWdlL2NhbGxiYWNrIiwiY2FsbGJhY2tCb2R5Ijoie1wiZmlsZVBhdGhcIjpcImRpcmVjdC9jN2VlYWNjZjU2ZDM0MzM3OWQ2Yjk4ZmYwNGYyZWFjNS5wbmdcIixcImlzQXVkaXRcIjoxLFwieC1pbWFnZS1hcHBcIjpcImRpcmVjdF9ibG9nXCIsXCJ0eXBlXCI6XCJibG9nXCIsXCJ1cmxNZDVcIjpcImM3ZWVhY2NmNTZkMzQzMzc5ZDZiOThmZjA0ZjJlYWM1XCIsXCJydHlwZVwiOlwibWFya2Rvd25cIixcImhvc3RuYW1lXCI6XCJodHRwczovL2ltZy1ibG9nLmNzZG5pbWcuY24vXCIsXCJzaXplXCI6XCIke3NpemV9XCIsXCJ4LWltYWdlLWRpclwiOlwiZGlyZWN0XCIsXCJ3aWR0aFwiOlwiJHtpbWFnZUluZm8ud2lkdGh9XCIsXCJ4LWltYWdlLXN1ZmZpeFwiOlwicG5nXCIsXCJ1c2VybmFtZVwiOlwibTBfNzI5NDczOTBcIixcImhlaWdodFwiOlwiJHtpbWFnZUluZm8uaGVpZ2h0fVwifSJ9',
          'dir': 'direct',
          'expire': '1718611892700',
          'filePath': 'direct/c7eeaccf56d343379d6b98ff04f2eac5.png',
          'host': 'https://csdn-img-blog.oss-cn-beijing.aliyuncs.com',
          'policy': 'eyJleHBpcmF0aW9uIjoiMjAyNC0wNi0xN1QwODoxMTozMi43MDBaIiwiY29uZGl0aW9ucyI6W1siY29udGVudC1sZW5ndGgtcmFuZ2UiLDAsMTA0ODU3NjAwXSxbInN0YXJ0cy13aXRoIiwiJGtleSIsImRpcmVjdC9jN2VlYWNjZjU2ZDM0MzM3OWQ2Yjk4ZmYwNGYyZWFjNS5wbmciXV19',
          'signature': '2hRKp5YO3epBJe5+Qt7Ngi7P/y4='},
 'message': None,
 'msg': 'success'}

下面利用 upload 得到的请求来构造 csdn 请求;

import requests
from requests_toolbelt.multipart.encoder import MultipartEncoder

def get_file(file_path):
	"""获取文件的二进制数据"""
    with open(file_path, mode='rb') as f:
        binary_data = f.read()
    return binary_data

headers = {
    'Accept': 'application/json, text/javascript, */*; q=0.01',
    'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6',
    'Connection': 'keep-alive',
    'Origin': 'https://editor.csdn.net',
    'Referer': 'https://editor.csdn.net/',
    'Sec-Fetch-Dest': 'empty',
    'Sec-Fetch-Mode': 'cors',
    'Sec-Fetch-Site': 'cross-site',
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36 Edg/126.0.0.0',
    'sec-ch-ua': '"Not/A)Brand";v="8", "Chromium";v="126", "Microsoft Edge";v="126"',
    'sec-ch-ua-mobile': '?0',
    'sec-ch-ua-platform': '"Windows"',
}

success_action_status = '200'

# upload 请求中获取到的数据
key = upload_data['data']['filePath']
policy = upload_data['data']['policy']
OSSAccessKeyId = upload_data['data']['accessId']
signature = upload_data['data']['signature']
callback = upload_data['data']['callbackUrl']

# 上传的图片位置,
file = get_file('') # 输入需要上传文件的位置

files = {
    'key': (None, key),
    'policy': (None, policy),
    'OSSAccessKeyId': (None, OSSAccessKeyId),
    'success_action_status': (None, '200'),
    'signature': (None, signature),
    'callback': (None, callback),
    'file': ('image.png', file, 'image/png'),
}

url = 'https://csdn-img-blog.oss-cn-beijing.aliyuncs.com/'
response = requests.post(url, headers=headers, files=files)

print(response.text)

得到 Json 数据如下

{'code': 200,
 'data': {'hostname': 'https://img-blog.csdnimg.cn/',
  'imageUrl': 'https://img-blog.csdnimg.cn/direct/97c5610606c140afb474800403140ea3.png',
  'width': '1138',
  'targetObjectKey': 'direct/97c5610606c140afb474800403140ea3.png',
  'x-image-suffix': 'png',
  'height': '239'},
 'msg': 'success'}

在其中 imageUrl 就表示上传的图片地址,同时,图片格式有许多种,面对不同的图片格式,在尝试观察后发现只需要修改 upload 请求中 parms 中的 x-image-suffixcsdn 请求中 files 中的 file

整合得到完整上传类如下:

import requests  
  
  
class UploadPic:  
    def __init__(self, cookie):  
        self.cookie = cookie  
  
        # 解析  
        self.file_path = ''  
        self.img_type = ''  
  
        # 两个请求体  
        self.upload_data = {}  
        self.csdn_data = {}  
        self.output_url = ''  
  
    def _get_file(self, file_path):  
        with open(file_path, mode='rb') as f:  
            binary_data = f.read()  
        return binary_data  
  
    def _upload_request(self):  
        headers = {  
            'accept': '*/*',  
            'accept-language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6',  
            'content-type': 'application/json',  
            'cookie': self.cookie,  
            'origin': 'https://editor.csdn.net',  
            'priority': 'u=1, i',  
            'referer': 'https://editor.csdn.net/',  
            'sec-ch-ua': '"Not/A)Brand";v="8", "Chromium";v="126", "Microsoft Edge";v="126"',  
            'sec-ch-ua-mobile': '?0',  
            'sec-ch-ua-platform': '"Windows"',  
            'sec-fetch-dest': 'empty',  
            'sec-fetch-mode': 'cors',  
            'sec-fetch-site': 'same-site',  
            'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36 Edg/126.0.0.0',  
        }  
  
        params = {  
            'type': 'blog',  
            'rtype': 'markdown',  
            'x-image-template': '',  
            'x-image-app': 'direct_blog',  
            'x-image-dir': 'direct',  
            'x-image-suffix': self.img_type,  
        }  
  
        url = 'https://imgservice.csdn.net/direct/v1.0/image/upload'  
  
        response = requests.get(url, params=params, headers=headers)  
        try:  
            self.upload_data = response.json()  
        except Exception as e:  
            return e  
  
    def _csdn_request(self):  
        headers = {  
            'Accept': 'application/json, text/javascript, */*; q=0.01',  
            'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6',  
            'Connection': 'keep-alive',  
            'Origin': 'https://editor.csdn.net',  
            'Referer': 'https://editor.csdn.net/',  
            'Sec-Fetch-Dest': 'empty',  
            'Sec-Fetch-Mode': 'cors',  
            'Sec-Fetch-Site': 'cross-site',  
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36 Edg/126.0.0.0',  
            'sec-ch-ua': '"Not/A)Brand";v="8", "Chromium";v="126", "Microsoft Edge";v="126"',  
            'sec-ch-ua-mobile': '?0',  
            'sec-ch-ua-platform': '"Windows"',  
        }  
  
        files = {  
            'key': (None, self.upload_data['data']['filePath']),  
            'policy': (None, self.upload_data['data']['policy']),  
            'OSSAccessKeyId': (None, self.upload_data['data']['accessId']),  
            'success_action_status': (None, '200'),  
            'signature': (None, self.upload_data['data']['signature']),  
            'callback': (None, self.upload_data['data']['callbackUrl']),  
            'file': (f'image.{self.img_type}', self._get_file(self.file_path), f'image/{self.img_type}'),  
        }  
  
        url = 'https://csdn-img-blog.oss-cn-beijing.aliyuncs.com/'  
  
        response = requests.post(url, headers=headers, files=files)  
        try:  
            self.csdn_data = response.json()  
            self.output_url = self.csdn_data['data']['imageUrl']  
        except Exception as e:  
            return e  
  
    def upload_image(self, file_path):  
        self.file_path = file_path  
        self.img_type = self.file_path.split('.')[-1]  
  
        exception_1 = self._upload_request()  
        assert exception_1 is None, exception_1  
        exception_2 = self._csdn_request()  
        assert exception_2 is None, exception_2  
  
        return self.output_url  
  
  
if __name__ == '__main__':  
    cookie = '' # 输入你的cookie  
    upload = UploadPic(cookie)  
    output_url = upload.upload_image('')  #输入你需要上传的文件位置
    print(output_url)

二、替换 MD 中的引用文件为在线链接

首先,肯定是整体替换而不是单个替换,因此我们的流程为:1. 上传所有文件,直到所有的文件都上传成功;2. 替换所有文件;

首先提取出 Markdown 中所有的图片信息,一般来说图片信息都在两个中括号之间 ![[ img_pic ]],使用 re 正则提取,代码如下;

import re

file_path = 'C:/Users/Administrator/Documents/Obsidian Vault/UE开发/My FirstGame Tutorial.md'

with open(file_path, mode='r', encoding='utf-8') as f:
    markdown_text = f.read()

image_lst = re.findall(r'(!\[\[.*\]\])', markdown_text)
posterior_image_lst = [item[3:-2] for item in image_lst]

提取出所有的 img_pic 后,我们需要在根目录下寻找文件,一般来说在 Markdown 中文件名是不重复的;

import os
from pathlib import Path

def get_target_image_path(target_path):
    walk_path = 'C:/Users/Administrator/Documents/Obsidian Vault/'
    for root, floders, files in os.walk(walk_path):
        for file in files:
            if file == target_path:
                return Path(root) / file

get_target_image_path(posterior_image_lst[0])

获取到了绝对位置后,我们可以将图片上传,在检查图片全部都上传完毕后,我们就可以替换 ![[ img_pic ]]

import os  
import re  
import requests  
from pathlib import Path  
from rich.progress import track  
  
  
class UploadPic:  
    def __init__(self, cookie):  
        self.cookie = cookie  
  
        # 解析  
        self.file_path = ''  
        self.img_type = ''  
  
        # 两个请求体  
        self.upload_data = {}  
        self.csdn_data = {}  
        self.output_url = ''  
  
    def _get_file(self, file_path):  
        with open(file_path, mode='rb') as f:  
            binary_data = f.read()  
        return binary_data  
  
    def _upload_request(self):  
        headers = {  
            'accept': '*/*',  
            'accept-language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6',  
            'content-type': 'application/json',  
            'cookie': self.cookie,  
            'origin': 'https://editor.csdn.net',  
            'priority': 'u=1, i',  
            'referer': 'https://editor.csdn.net/',  
            'sec-ch-ua': '"Not/A)Brand";v="8", "Chromium";v="126", "Microsoft Edge";v="126"',  
            'sec-ch-ua-mobile': '?0',  
            'sec-ch-ua-platform': '"Windows"',  
            'sec-fetch-dest': 'empty',  
            'sec-fetch-mode': 'cors',  
            'sec-fetch-site': 'same-site',  
            'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36 Edg/126.0.0.0',  
        }  
  
        params = {  
            'type': 'blog',  
            'rtype': 'markdown',  
            'x-image-template': '',  
            'x-image-app': 'direct_blog',  
            'x-image-dir': 'direct',  
            'x-image-suffix': self.img_type,  
        }  
  
        url = 'https://imgservice.csdn.net/direct/v1.0/image/upload'  
  
        response = requests.get(url, params=params, headers=headers)  
        try:  
            self.upload_data = response.json()  
        except Exception as e:  
            return e  
  
    def _csdn_request(self):  
        headers = {  
            'Accept': 'application/json, text/javascript, */*; q=0.01',  
            'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6',  
            'Connection': 'keep-alive',  
            'Origin': 'https://editor.csdn.net',  
            'Referer': 'https://editor.csdn.net/',  
            'Sec-Fetch-Dest': 'empty',  
            'Sec-Fetch-Mode': 'cors',  
            'Sec-Fetch-Site': 'cross-site',  
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36 Edg/126.0.0.0',  
            'sec-ch-ua': '"Not/A)Brand";v="8", "Chromium";v="126", "Microsoft Edge";v="126"',  
            'sec-ch-ua-mobile': '?0',  
            'sec-ch-ua-platform': '"Windows"',  
        }  
  
        files = {  
            'key': (None, self.upload_data['data']['filePath']),  
            'policy': (None, self.upload_data['data']['policy']),  
            'OSSAccessKeyId': (None, self.upload_data['data']['accessId']),  
            'success_action_status': (None, '200'),  
            'signature': (None, self.upload_data['data']['signature']),  
            'callback': (None, self.upload_data['data']['callbackUrl']),  
            'file': (f'image.{self.img_type}', self._get_file(self.file_path), f'image/{self.img_type}'),  
        }  
  
        url = 'https://csdn-img-blog.oss-cn-beijing.aliyuncs.com/'  
  
        response = requests.post(url, headers=headers, files=files)  
        try:  
            self.csdn_data = response.json()  
            self.output_url = self.csdn_data['data']['imageUrl']  
        except Exception as e:  
            return e  
  
    def upload_image(self, file_path):  
        self.file_path = file_path  
        self.img_type = self.file_path.split('.')[-1]  
  
        exception_1 = self._upload_request()  
        assert exception_1 is None, exception_1  
        exception_2 = self._csdn_request()  
        assert exception_2 is None, exception_2  
  
        return self.output_url  
  
  
class CSDNTransform:  
    def __init__(self, upload:UploadPic, file_path, walk_path='C:/Users/Administrator/Documents/Obsidian Vault/'):  
        self.upload = upload  
        self.file_path = file_path  
        self.walk_path = walk_path  
  
        self.markdown_text = ''  
        self.image_lst = []  
        self.posterior_image_lst = []  
        self.image_2_url_dic = {}  
  
    def _get_markdown_text(self):  
        with open(self.file_path, mode='r', encoding='utf-8') as f:  
            markdown_text = f.read()  
        self.markdown_text = markdown_text  
  
    def _process_markdown_text(self):  
        image_lst = re.findall(r'(!\[\[.*]])', self.markdown_text)  
        posterior_image_lst = [item[3:-2] for item in image_lst]  
  
        self.image_lst = image_lst  
        self.posterior_image_lst = posterior_image_lst  
  
    def _get_target_image_path(self, target_path):  
        for root, floders, files in os.walk(self.walk_path):  
            for file in files:  
                if file == target_path:  
                    return str(Path(root) / file)  
  
    def _get_the_url_of_image(self, image_path):  
        image_url = self.upload.upload_image(image_path)  
        return image_url  
  
    def get_the_urls(self):  
        self._get_markdown_text()  
        self._process_markdown_text()  
  
        not_exist_image_index = []  
  
        for ix, (origin_image, target_path) in track(enumerate(zip(self.image_lst, self.posterior_image_lst))):  
            image_path = self._get_target_image_path(target_path)  
            if image_path is not None:  
                image_url = self._get_the_url_of_image(image_path)  
                self.image_2_url_dic[origin_image] = image_url  
            else:  
                not_exist_image_index.append(ix)  
  
        # 清楚掉需要删除的index  
        num = 0  
        for ix in not_exist_image_index:  
            del self.image_lst[ix-num]  
            del self.posterior_image_lst[ix-num]  
            num += 1  
  
    def _the_transform_data_from(self, image_url):  
        data_form = f"""\n<div align=center><img src="{image_url}"></div>\n"""  
        return data_form  
  
    def _save_markdown_text(self, output_file='markdown_processed.txt'):  
        with open(output_file, mode='w', encoding='utf-8') as f:  
            f.write(self.markdown_text)  
  
    def get_transform(self):  
        self.get_the_urls()  
  
        # Judge the length  
        assert len(self.image_lst) == len(self.image_2_url_dic), f"上传成功{len(self.image_2_url_dic)}张图片,总共有{len(self.image_lst)}张图片"  
  
        for origin_image, image_url in self.image_2_url_dic.items():  
            self.markdown_text = self.markdown_text.replace(origin_image, self._the_transform_data_from(image_url))  
  
        self._save_markdown_text()
  
if __name__ == '__main__':  
    cookie = ''  # 输入你的cookie
    file_path = ''  # 输入你要转换的markdown文件地址
    upload = UploadPic(cookie)  
    transform = CSDNTransform(upload, file_path)  
    markdown_text = transform.get_transform()

	# 修改后的 Markdown 在当前目录的 markdown_processed.txt 文件中

参考

requests库post请求参数data、json和files的使用_requests post data-CSDN博客
HTTP协议之multipart/form-data请求分析_http form-data请求-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/719239.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

VBA学习(6): 调整工作表中所有图表尺寸并使其大小相同

有时候&#xff0c;我们想要将工作表中的所有图表进行缩放操作&#xff0c;且要求这些图表调整后的尺寸大小相同。如果使用手动拖放调整&#xff0c;看似大小相同&#xff0c;实际可能有差异。当然&#xff0c;也可以选取所有的图表后&#xff0c;在工作表选项卡中输入其宽度和…

TOP10!YashanDB斩获广东省优秀信创产品与解决方案双料荣誉

近日&#xff0c;2024广东软件风云榜结果出炉&#xff0c;表彰为广东软件产业和数字经济、新型工业化发展作出突出贡献的企业、企业家、优秀产品等。深算院崖山数据库系统 YashanDB荣获广东省“2024年优秀信息技术应用创新产品TOP10”和“2024年优秀信息技术应用创新行业应用解…

LeetCode 1789, 6, 138

目录 1789. 员工的直属部门题目链接表要求知识点思路代码 6. Z 字形变换题目链接标签思路代码 138. 随机链表的复制题目链接标签思路代码 1789. 员工的直属部门 题目链接 1789. 员工的直属部门 表 表Employee的字段为employee_id&#xff0c;department_id和primary_flag。…

SpringBoot购物网站

摘要 随着信息技术的高速发展&#xff0c;二十一世纪的网络技术和网络应用正在快速融入人们的生活&#xff0c;并且由于网络服务以及网络应用日渐普及&#xff0c;人们对于现在生活的需求也随之增长&#xff0c;而网上购物的便捷对人们的吸引力越来越大&#xff0c;购物网站可…

Android 大话binder通信 (上)

戳蓝字“牛晓伟”关注我哦&#xff01; 用心坚持输出易读、有趣、有深度、高质量、体系化的技术文章 本文摘要 用故事的方式把binder通信的整个过程都描述出来&#xff0c;binder通信都经历了哪些节点&#xff0c;在这些节点上的数据有哪些变化&#xff0c;同时还对binder通…

触控MCU芯片(1):英飞凌PSoC第6代第7代

前言: 说到触摸MCU芯片,这个历史也是很久了,比如日常经常接触到的洗衣机、电冰箱、小家电,隔着一层玻璃,轻轻一按就能识别按键,感觉比过去纯机械式的按键更高级更美观,不仅白电,现在很多汽车也都在进行触摸按键的改版,不再使用笨重的机械按键,比如空调调温按键、档位…

淘宝评论电商API接口,揭示用户真实评价

随着互联网的快速发展&#xff0c;电子商务已经成为了人们生活中不可或缺的一部分。淘宝作为中国最大的在线购物平台&#xff0c;拥有数以亿计的消费者和商家。而用户评价作为消费者了解商品和服务的重要途径&#xff0c;对于商家的信誉和销售有着至关重要的影响。因此&#xf…

SCADA软件地毯式介绍,你想知道的都在这里.

很多小伙伴对SCADA很陌生&#xff0c;殊不知这个可是智慧工业制造的大脑和中枢神经&#xff0c;很多指令的发出&#xff0c;监控状态的现实都得通过这个系统&#xff0c;本文详解介绍一下什么是SCADA&#xff0c;重大作用&#xff0c;其在工业制造中的位置&#xff0c;以及市面…

Export S parameter sweep data 导出 S 参数扫描代码

Export S parameter sweep data 导出 S 参数扫描代码 正文正文 相信有不少小伙伴们会比较苦恼一件事情,就是 Lumerical Script 中的绘图并不智能。功能较为简陋以至于图像展现时不够美观,因此,很多时候我们需要将仿真数据导出使用。那么如何导出仿真数据呢?在 Lumerical S…

【Linux进程通信】Linux进程间的无声对话:匿名管道与命名管道技术

W...Y的主页 &#x1f60a; 代码仓库分享 &#x1f495; 前言&#xff1a;我们已经知道了进程和文件的基本理论&#xff0c;知道了进程和文件的重要性。进程具有独立性&#xff0c;所以两个进程不能直接通信&#xff0c;那么进程间应该怎样通信呢&#xff1f;我们今天来解开其…

物联网技术-第4章物联网通信技术-4.1计算机网络

目录 1.1计算机网络拓扑与组成 &#xff08;1&#xff09;全连通式网络 &#xff08;2&#xff09;星型网 &#xff08;3&#xff09;环形网 &#xff08;4&#xff09;总线网 &#xff08;5&#xff09;不规则型网 1.2数据交换类型 &#xff08;1&#xff09;电路交换网 &…

硬件开发笔记(十八):核心板与底板之间的连接方式介绍说明:板对板连接器

若该文为原创文章&#xff0c;转载请注明原文出处 本文章博客地址&#xff1a;https://hpzwl.blog.csdn.net/article/details/139663096 长沙红胖子Qt&#xff08;长沙创微智科&#xff09;博文大全&#xff1a;开发技术集合&#xff08;包含Qt实用技术、树莓派、三维、OpenCV…

DSP28335:独立按键控制LED灯

做任何事情不可操之过急&#xff0c;虽然我们可能在之前的单片机学过相关的原理&#xff0c;但是一个新的单片机依然有他的学习的地方&#xff0c;之前我觉得很简单&#xff0c;就跳过这个学习&#xff0c;结果到后面就很浮躁&#xff0c;导致后面的内容与这一章相连接的时候&a…

利用这个css属性,你也能轻松实现一个新手引导库

相信大家或多或少都在各种网站上使用过新手引导&#xff0c;当网站提供的功能有点复杂时&#xff0c;这是一个对新手非常友好的功能&#xff0c;可以跟随新手引导一步一步了解网站的各种功能&#xff0c;我们要做的只是点击下一步或者上一步&#xff0c;网站就能滚动到指定位置…

齐普夫定律在循环神经网络中的语言模型的应用

目录 齐普夫定律解释公式解释图与公式的关系代码与图的分析结论 使用对数表达方式的原因1. 线性化非线性关系2. 方便数据可视化和分析3. 降低数值范围4. 方便参数估计公式详细解释结论 来自&#xff1a;https://zh-v2.d2l.ai/chapter_recurrent-neural-networks/language-model…

智慧校园发展趋势:2024年及未来教育科技展望

展望2024年及未来的教育科技领域&#xff0c;智慧校园的发展正引领着一场教育模式的深刻变革&#xff0c;其核心在于更深层次地融合技术与教育实践。随着人工智能技术的不断成熟&#xff0c;个性化学习将不再停留于表面&#xff0c;而是深入到每个学生的个性化需求之中。通过精…

电感的本质是什么

什么是电感&#xff1f; 电感器件一般是指螺线圈&#xff0c;由导线圈一圈靠一圈地绕在绝缘管上&#xff0c;绝缘管可以是空心的&#xff0c;也可以包含铁芯或磁粉芯。 为什么把’线’绕成’圈’就是电感&#xff1f; 电感的工作原理非常抽象&#xff0c;为了解释什么是电感…

单片机 PWM输入捕获【学习记录】

前言 学习是永无止境的&#xff0c;就算之前学过的东西再次学习一遍也能狗学习到很多东西&#xff0c;输入捕获很早之前就用过了&#xff0c;但是仅仅是照搬例程没有去进行理解。温故而知新&#xff01; 定时器 定时器简介 定时器的分类 高级定时器 通用定时器 基本定时器…

Facebook与地方文化:数字平台的多元表达

在当今数字化时代&#xff0c;社交媒体不仅仅是人们交流的工具&#xff0c;更是促进地方文化传播和表达的重要平台。作为全球最大的社交网络之一&#xff0c;Facebook在连接世界各地用户的同时&#xff0c;也成为了地方文化多元表达的重要舞台。本文将深入探讨Facebook如何通过…

LabVIEW的热门应用

LabVIEW是一种图形化编程语言&#xff0c;因其易用性和强大的功能&#xff0c;在多个行业和领域中广泛应用。介绍LabVIEW在以下五个热门应用领域中的使用情况&#xff0c;&#xff1a;工业自动化、医疗设备与生物医学工程、科学研究与实验室自动化、能源管理与智能电网、航空航…