最近 GitHub 被墙的很严重, 之前的 GitHub 图床都不能用了... 写个简单的脚本, 将在线的 GitHub 图片转换成本地图片, 然后再调用 VNote 自带的图床上传到码云上岂不是美滋滋!

不多 bb, 直接上脚本:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Date    : 2020-05-29 20:36:33
# @Author  : 江南小虫虫 (fwh13612265462@gmail.com)
# @Link    : https://fengwenhua.top

import requests
import os
import re
import pyperclip
import urllib3
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
from requests.adapters import HTTPAdapter
from requests.packages.urllib3.util import Retry

##########################################################################################
# 文件或文件夹 绝对路径
user_input_path = '/Users/fengwenhua/Library/Mobile Documents/com~apple~CloudDocs/VNote/信息安全/pwn/入门'
##########################################################################################


def find_md_file(dir):
    """根据给出的目录, 找到该目录下的所有的markdown文件
    :param dir: 目录
    :return: markdown的绝对路径列表
    """
    md_files = []
    for root, dirs, files in os.walk(dir):
        # print('当前目录路径: ', root)  # 当前目录路径
        # print('当前路径下所有子目录: ', dirs)  # 当前路径下所有子目录
        # print('当前路径下所有非目录子文件: ', files)  # 当前路径下所有非目录子文件
        for file in files:
            if file.endswith('.md'):
                md_files.append(root + "/" + file)
    # print('总共markdown文件数量是: ', len(md_files))
    # for file in md_files:
    #     print(file)
    return md_files


def download_img(md_file_dir, image_url):
    """下载图片到本地
    :param image_path: 要上传的图片路径
    :return: 下载成功返回图片链接, 失败返回False
    """
    #print("要处理的文件名是: ")
    file_name = image_url.split("/")[-1]
    # print(file_name)
    proxies = {'http': 'http://proxy.lfk.360es.cn:3128',
               'https': 'http://proxy.lfk.360es.cn:3128'}
    try:
        s = requests.Session()
        s.mount('https://', HTTPAdapter(max_retries=Retry(total=5,
                                                          method_whitelist=frozenset(['GET', 'POST']))))  # 设置 post()方法进行重访问
        r = s.get(image_url, proxies=proxies, verify=False, timeout=20)
        # 获取的文本实际上是图片的二进制文本
        img = r.content
        # 将他拷贝到本地文件 w 写  b 二进制  wb代表写入二进制文本
        if "#" in file_name:
            file_name = file_name.split("#")[0]
        with open(md_file_dir + '/_v_images/' + file_name, 'wb') as f:
            f.write(img)
        return image_url.split("/")[-1]
    except Exception as e:
        print("出现异常")
        print(e)
        return False


def find_download_replace_img(md_file):
    """根据给出的markdown文件, 找到里面的远程图片, 下载到本地的 _v_images 文件夹
    :param md_file: md文件
    :return: 全部是本地图片的markdown文件
    """
    print("开始处理 ", md_file)
    content = ""
    with open(md_file, "r", encoding='utf8') as f:
        content = f.read()
    # print("markdown文档所在路径: ", os.path.dirname(md_file))
    md_file_dir = os.path.dirname(md_file)
    # print('文件内容: ', content)
    pattern = re.compile(r'!\[.*?\]\((.*?)\)')

    finded_img_urls = pattern.findall(content)
    print('该文档里的所有图片链接: ')
    print(finded_img_urls)

    print("\n")
    have_remote_img = False
    if finded_img_urls:  # 找到图片的链接
        for url in finded_img_urls:
            if "_v_images" in url or "https://gitee.com/fengwenhua/ImageBed" in url:  # 已经是本地图片或者 gitee, 忽略
                continue
            else:  # 在线图片
                # print("文档绝对路径: ", md_file)
                # print("文档名: ", os.path.split(md_file)[1])
                # print("在线图片: ", url)
                have_remote_img = True

                pic_read_size = None
                if(" =" in url):  # 图片缩放
                    pic_read_size = " =" + \
                        url.split(" =")[1]  # 缩放的内容
                    url = url.split(" =")[0]
                print("处理: ", url)
                file_name = url.split("/")[-1]
                if "png" in file_name or "jpg" in file_name or "gif" in file_name:
                    pass
                else:
                    url = url + ".png"
                # 本地路径找出来之后, 可以下载了
                img_url = download_img(md_file_dir, url)
                if not img_url:
                    print(url + ' 下载失败')
                    return False
                else:
                    # 上传完成, 拿到链接, 替换原来的链接
                    if "#" in img_url:
                        img_url = img_url.split("#")[0]
                    img_url = "_v_images/" + img_url
                    #print('图片的新链接是: ', img_url)
                    if pic_read_size:
                        img_url = img_url + pic_read_size
                    #print("最终要替换的 url 如下:")
                    # print(img_url)
                    content = content.replace(url, img_url)
                    with open(md_file, "w", encoding='utf8') as f:
                        f.write(content)
                    print(url + " 已处理完成!")
        # 最后将内容写进文件
        if have_remote_img:
            # with open(md_file, "w", encoding='utf8') as f:
            #     f.write(content)
            print(md_file + " 已处理完成!")
            # pyperclip.copy(content)
            # print(md_file + " 已复制到剪切板,赶紧处理一下!")

        else:
            print(md_file + " 没有需要下载的远程图片")
        return True
    else:
        print(md_file + " 没有图片")
        return True


if __name__ == '__main__':
    if os.path.exists(user_input_path):  # 路径存在
        if os.path.isfile(user_input_path):  # 如果是文件
            if not find_download_replace_img(user_input_path):
                print("未知原因导致图片下载失败, 请检查具体原因, 然后重试")
                exit(-1)
        elif os.path.isdir(user_input_path):  # 如果是文件夹
            md_files = find_md_file(user_input_path)  # 根据给出的目录寻找md文件
            for file in md_files:
                # 对于每个md文件, 分析其中的远程图片, 然后下载, 替换
                if not find_download_replace_img(file):
                    print("未知原因导致图片下载失败, 请检查具体原因, 然后重试")
                    exit(-1)
                else:
                    print()
    else:
        print('请给出正确的路径')
        exit(-1)

脚本需要设置要处理的文件/文件夹的路径, 并且设置代理!

脚本基本够用了, 如果有特殊需求, 请自行修改!

ps: 本来想写进 VNote 里面的, 但是最近事情太多了, 没时间, 先凑合着用吧!

最后修改:2021 年 04 月 19 日 04 : 15 PM
如果觉得我的文章对你有用,请随意赞赏