微博图床挂了!

news2024/9/25 21:26:57

bba3387aa3575e4a9a2ab6fc8805f207.png

一直担心的事情还是发生了。

作为hexo多年的使用者,微博图床一直是我的默认选项,hexo+typora+iPic更是我这几年写文章的黄金组合。而图床中,新浪图床一直都是我的默认选项,速度快、稳定同时支持大图片批量上传更是让其成为了众多图床工具的默认选项。虽然今年早些的时候,部分如「ws1、ws2……」的域名就已经无法使用了,但通过某些手段还是可以让其存活的,而最近,所有调用的微博图床图片都无法加载并提示“403 Forbidden”了。

b3e5551d5741207a3cf7d65997743b85.png

💡Tips:图片中出现的Tengine是淘宝在Nginx的基础上修改后开源的一款Web服务器,基本上,Tengine可以被看作一个更好的Nginx,或者是Nginx的超集,详情可参考👉淘宝Web服务器Tengine正式开源 - The Tengine Web Server

刚得知这个消息的时候,我的第一想法其实是非常生气的,毕竟自己这几年上千张图片都是用的微博图床,如今还没备份就被403了,可仔细一想,说到底还是把东西交在别人手里的下场,微博又不是慈善企业,也要控制成本,一直睁一只眼闭一只眼让大家免费用就算了,出了问题还是不太好怪到微博上来的。

那么有什么比较好的办法解决这个问题呢?

查遍了网上一堆复制/粘贴出来的文章,不是开启反向代理就是更改请求头,真正愿意从根本上解决问题的没几个。

如果不想将自己沉淀的博客、文章托管在印象笔记、notion、语雀这些在线平台的话,想要彻底解决这个问题最好的方式是:自建图床!

为了更好的解决问题,我们先弄明白,403是什么,以及我们存在微博上的图片究竟是如何被403的。

403

百度百科,对于403错误的解释很简单

403错误是一种在网站访问过程中,常见的错误提示,表示资源不可用。服务器理解客户的请求,但拒绝处理它,通常由于服务器上文件或目录的权限设置导致的WEB访问错误。

所以说到底是因为访问者无权访问服务器端所提供的资源。而微博图床出现403的原因主要在于微博开启了防盗链。

防盗链的原理很简单,站点在得知有请求时,会先判断请求头中的信息,如果请求头中有Referer信息,然后根据自己的规则来判断Referer头信息是否符合要求,Referer 信息是请求该图片的来源地址。

如果盗用网站是 https 的 协议,而图片链接是 http 的话,则从 https 向 http 发起的请求会因为安全性的规定,而不带 referer,从而实现防盗链的绕过。官方输出图片的时候,判断了来源(Referer),就是从哪个网站访问这个图片,如果是你的网站去加载这个图片,那么 Referer 就是你的网站地址;你的网址肯定没在官方的白名单内,(当然作为可操作性极强的浏览器来说 referer 是完全可以伪造一个官方的 URL 这样也也就也可以饶过限制🚫)所以就看不到图片了。

a7822c1a52e29bb37e36134338321c8b.png

解决问题

解释完原理之后我们发现,其实只要想办法在自己的个人站点中设置好referer就可以解决这个问题,但说到底也只是治标不治本,真正解决这个问题就是想办法将图片迁移到自己的个人图床上。

现在的图床工具很多,iPic、uPic、PicGo等一堆工具既免费又开源,问题在于选择什么云存储服务作为自己的图床以及如何替换自己这上千张图片。

  1. 选择什么云存储服务

  2. 如何替换上千张图片

什么是OSS以及如何选择

「OSS」的英文全称是Object Storage Service,翻译成中文就是「对象存储服务」,官方一点解释就是对象存储是一种使用HTTP API存储和检索非结构化数据和元数据对象的工具。

白话文解释就是将系统所要用的文件上传到云硬盘上,该云硬盘提供了文件下载、上传等一列服务,这样的服务以及技术可以统称为OSS,业内提供OSS服务的厂商很多,知名常用且成规模的有阿里云、腾讯云、百度云、七牛云、又拍云等。

对于我们这些个人用户来说,这些云厂商提供的服务都是足够使用的,我们所要关心的便是成本💰。

笔者使用的是七牛云,它提供了10G的免费存储,基本已经够用了。

有人会考虑将GitHub/Gitee作为图床,并且这样的文章在中文互联网里广泛流传,因为很多人的个人站点都是托管在GitHub Pages上的,但是个人建议是不要这么做。

首先GitHub在国内的访问就很受限,很多场景都需要科学上网才能获得完整的浏览体验。再加上GitHub官方也不推荐将Git仓库存储大文件,GitHub建议仓库保持较小,理想情况下小于 1 GB,强烈建议小于 5 GB。

如何替换上千张图片

替换文章中的图片链接和“把大象放进冰箱里”步骤是差不多的

  1. 下载所有的微博图床的图片

  2. 上传所有的图片到自己的图床(xx云)

  3. 对文本文件执行replaceAll操作

考虑到我们需要迁移的文件数量较多,手动操作肯定是不太可行的,因此我们可以采用代码的方式写一个脚本完成上述操作。考虑到自己已经是一个成熟的Java工程师了,这个功能就干脆用Java写了。

为了减少代码量,精简代码结构,我这里引入了几个第三方库,当然不引入也行,如果不引入有一些繁琐而又简单的业务逻辑需要自己实现,有点浪费时间了。

整个脚本逻辑非常简单,流程如下:

499127f523237ce7339c8cb043975150.png

获取博客文件夹下的Markdown文件

这里我们直接使用hutool这个三方库,它内置了很多非常实用的工具类,获取所有markdown文件也变得非常容易

/**
 * 筛选出所有的markdown文件
 */
public static List<File> listAllMDFile() {
    List<File> files = FileUtil.loopFiles(VAULT_PATH);
    return files.stream()
       .filter(Objects::nonNull)
        .filter(File::isFile)
        .filter(file -> StringUtils.endsWith(file.getName(), ".md"))
        .collect(Collectors.toList());
}

获取文件中的所有包含微博图床的域名

通过Hutools内置的FileReader我们可以直接读取markdown文件的内容,因此我们只需要解析出文章里包含微博图床的链接即可。我们可以借助正则表达式快速获取一段文本内容里的所有url,然后做一下filter即可。

/**
 * 获取一段文本内容里的所有url
 *
 * @param content 文本内容
 * @return 所有的url
 */
public static List<String> getAllUrlsFromContent(String content) {
    List<String> urls = new ArrayList<>();
    Pattern pattern = Pattern.compile(
        "\\b(((ht|f)tp(s?)\\:\\/\\/|~\\/|\\/)|www.)" + "(\\w+:\\w+@)?(([-\\w]+\\.)+(com|org|net|gov"
            + "|mil|biz|info|mobi|name|aero|jobs|museum" + "|travel|[a-z]{2}))(:[\\d]{1,5})?"
            + "(((\\/([-\\w~!$+|.,=]|%[a-f\\d]{2})+)+|\\/)+|\\?|#)?" + "((\\?([-\\w~!$+|.,*:]|%[a-f\\d{2}])+=?"
            + "([-\\w~!$+|.,*:=]|%[a-f\\d]{2})*)" + "(&(?:[-\\w~!$+|.,*:]|%[a-f\\d{2}])+=?"
            + "([-\\w~!$+|.,*:=]|%[a-f\\d]{2})*)*)*" + "(#([-\\w~!$+|.,*:=]|%[a-f\\d]{2})*)?\\b");
    Matcher matcher = pattern.matcher(content);
    while (matcher.find()) {
        urls.add(matcher.group());
    }
    return urls;
}

下载图片

用Java下载文件的代码在互联网上属实是重复率最高的一批检索内容了,这里就直接贴出代码了。

public static void download(String urlString, String fileName) throws IOException {
    File file = new File(fileName);
    if (file.exists()) {
        return;
    }
    URL url = null;
    OutputStream os = null;
    InputStream is = null;
    try {
        url = new URL(urlString);
        URLConnection con = url.openConnection();
        // 输入流
        is = con.getInputStream();
        // 1K的数据缓冲
        byte[] bs = new byte[1024];
        // 读取到的数据长度
        int len;
        // 输出的文件流
        os = Files.newOutputStream(Paths.get(fileName));
        // 开始读取
        while ((len = is.read(bs)) != -1) {
            os.write(bs, 0, len);
        }
    } finally {
        if (os != null) {
            os.close();
        }
        if (is != null) {
            is.close();
        }
    }
}

上传图片

下载完图片后我们便要着手将下载下来的图片上传至我们自己的云存储服务了,这里直接给出七牛云上传图片的文档链接了,文档里写的非常详细,我就不赘述了👇

Java SDK_SDK 下载_对象存储 - 七牛开发者中心

全局处理

通过阅读代码的细节,我们可以发现,我们的方法粒度是单文件的,但事实上,我们可以先将所有的文件遍历一遍,统一进行图片的下载、上传与替换,这样可以节约点时间。

统一替换的逻辑也很简单,我们申明一个全局Map,

private static final Map<String, String> URL_MAP = Maps.newHashMap();

其中,key是旧的新浪图床的链接,value是新的自定义图床的链接。

我们将listAllMDFile这一步中所获取到的所有文件里的所有链接保存于此,下载时只需遍历这个Map的key即可获取到需要下载的图片链接。然后将上传后得到的新链接作为value存在到该Map中即可。

全文替换链接并更新文件

有了上述这些处理步骤,接下来一步就变的异常简单,只需要遍历每个文件,将匹配到全局Map中key的链接替换成Map中的value即可。

/**
 * 替换所有的图片链接
 */
private static String replaceUrl(String content, Map<String, String> urlMap) {
    for (Map.Entry<String, String> entry : urlMap.entrySet()) {
        String oldUrl = entry.getKey();
        String newUrl = entry.getValue();
        if (StringUtils.isBlank(newUrl)) {
            continue;
        }
    content = RegExUtils.replaceAll(content, oldUrl, newUrl);
    }
    return content;
}

我们借助commons-lang实现字符串匹配替换,借助Hutools实现文件的读取和写入。

files.forEach(file -> {
    try {
        FileReader fileReader = new FileReader(file.getPath());
        String content = fileReader.readString();
        String replaceContent = replaceUrl(content, URL_MAP);
        FileWriter writer = new FileWriter(file.getPath());
        writer.write(replaceContent);
    } catch (Throwable e) {
        log.error("write file error, errorMsg:{}", e.getMessage());
    }
});

为了安全起见,最好把文件放在新的目录中,不要直接替换掉原来的文件,否则程序出现意外就麻烦了。

接下来我们只需要运行程序,静待备份结果跑完即可。

以上就是本文的全部内容了,希望对你有所帮助

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

工具及方法 - 设计你的文件夹结构

电脑上资料总是很多&#xff0c;要如何管理&#xff0c;是每个人都需要处理的问题。 如果处理不好&#xff0c;时间一长&#xff0c;很多资料就可能不知所踪或者难以查找。 出现这种情况&#xff0c;让人头疼&#xff0c;还浪费了时间&#xff0c;降低了工作效率。 所以&…

springboot服务启动JMX监控

前言 java应用部署下在生产环境&#xff0c;肯定是少不了监控的&#xff0c;比如说我们想要监控JVM的线程使用情况&#xff0c;内存使用情况等等。这时候我们可以采用JMX来实现JVM监控&#xff0c;如果对JMX不熟悉&#xff0c;可以参见之前的 精通JVM监控&#xff0c;不知道J…

Java技能树-操作符(二)-练习篇

按位操作符 下面代码执行后的结果是&#xff1a; System.out.println(1 & 2); System.out.println(1 | 2);答案是&#xff1a;A 正确结果是&#xff1a; 0 3Process finished with exit code 0十进制&#xff1a;1 二进制&#xff1a;0000 0001 十进制&#xff1a;2 二进…

【SpringCloud】Erauke的基本原理与使用

【SpringCloud】Erauke的基本原理与使用 一、Eureka-提供者与消费者 【问】如果服务A调用了服务B&#xff0c;而服务B又调用了服务C&#xff0c;服务B的角色是什么&#xff1f; 二、Eureka的结构和作用 什么是Eureka&#xff1f; Eureka 解决服务调用的问题 order-servic…

计算机论文的参考文献,应该怎么引用? - 易智编译EaseEditing

参考文献的引用格式&#xff0c;要看期刊的要求&#xff0c;期刊会规定文章格式&#xff0c;这里面就包括参考文献的格式。 如果不是投稿到期刊&#xff0c;也会有相应的要求&#xff0c;按要求来就行。 不仅很参考文献的格式&#xff0c;还有很多细节也要注意&#xff1a; …

【Java多线程】创建多线程的方式二---实现Runnable接口(多窗口卖票)

题&#xff1a;创建三个窗口卖票&#xff0c;总票数为100张 1.继承Thread类的方式&#xff1a; 因为是三个窗口共卖100张所以我们在定义ticket时要用到static来修饰 private static int ticket 100; 代码如下&#xff1a; class Window extends Thread{private static in…

k8s在华为openeuler搭建

参考文献 Kubernetes1.26.0部署(Ubuntu/CentOS)未完待续https://blog.csdn.net/weixin_67405599/article/details/128466282 Kubeadm 快速搭建 k8s v1.24.1 集群&#xff08;openEuler 22.03 LTS&#xff09;https://huaweicloud.csdn.net/633119cbd3efff3090b52068.html op…

宽度优先搜索算法(BFS)详解(超级详细讲解,附有大图)

目录 一.宽度优先搜索&#xff08;BFS&#xff09;是什么&#xff1f; 二.图解宽搜&#xff08;BFS&#xff09; 三.对比与发现 四。工具——队列 五.模板 六.最后 一.宽度优先搜索&#xff08;BFS&#xff09;是什么&#xff1f; 百度百科这样说&#xff1a; 宽度优先搜索…

一文讲透:质量管理的历史

&#xff08;本文摘自《软件质量保证与管理&#xff08;第2版&#xff09;》&#xff0c;清华大学出版社&#xff0c;2020&#xff09;1875年泰勒制诞生&#xff0c;意味着科学管理的开始&#xff0c;最初的质量管理也就是将检验活动与其他职能分离&#xff0c;出现了专职的检验…

2022-2023年中国数字经济投融资及创新展望研究报告(附下载链接)

省时查报告-专业、及时、全面的行研报告库省时查方案-专业、及时、全面的营销策划方案库【免费下载】2022年12月份热门报告盘点罗振宇2023年跨年演讲PPT原稿吴晓波2022年年终秀演讲PPT原稿2023年&#xff0c;如何科学制定年度规划&#xff1f;《底层逻辑》高清配图清华大学256页…

AF647 DBCO荧光染料,AF647 DBCO,Alexa Fluor 647 DBCO,AF-647, 二苯并环辛

一、产品描述&#xff1a;Alexa Fluor 647是一种明亮且可感光的远红色染料&#xff0c;其激发非常适合633 nm激光线。Alexa Fluor 647染料用于在成像和流式细胞仪中产生稳定的信号&#xff0c;在pH 4到pH 10之间为水溶性且对pH不敏感。这种长波长Alexa Fluor 染料的荧光肉眼看不…

什么是元器件二筛,为何要二筛,如何二筛,二筛的要求与分级要点总结

&#x1f3e1;《电子元器件学习目录》 目录1&#xff0c;什么是二筛2&#xff0c;为何要二筛3&#xff0c;如何进行二筛4&#xff0c;二筛的要求5&#xff0c;二筛的分级6&#xff0c;总结1&#xff0c;什么是二筛 电子元器件测试筛选即元器件二次筛选&#xff0c;又被简称为二…

Spring @Autowired 用法

Spring Autowired 用法首先看下Component举例 1 :举例 2 :验证是否调用的是默认构造器如何&#xff0c;在启动的时候执行有参数的构造函数&#xff1f;&#xff1f;&#xff0c;这就要看Autowired注解了&#xff01;Autowired注解首先看下Component 在类级别上添加了Component…

Flask入门教程(视频教程笔记)

初始化flask项目 前面的python环境之类的就不说了。 该博客是看 Flask 入门 这个视频教程写的笔记&#xff0c;如果你想入门一下Flask&#xff0c;可以看看这个课&#xff0c;虽然简短&#xff0c;但是入门部分讲的很好&#xff0c;同时可以利用这篇博客复习复习。如果你想了解…

二、MES的生态链

1、MES功能模块图1、 符合MESA/ISA-95标准&#xff0c;基于SOA架构&#xff0c;技术架构与业务架构分离&#xff0c;实现多厂分布式部署具备标准化模型组件&#xff0c;可根据客户需求选取标准组件、或调整业务对象脚本&#xff0c;组合成全新的业务组件&#xff0c;实现企业ME…

电动汽车热管理方案

热管理技术作为汽车节能、提高经济性和保障安全性的重要措施&#xff0c;在汽车研发过程中具有重要作用。传统燃油汽车的热管理系统主要包括发动机、变速器散热系统和汽车空调&#xff0c;而电动汽车的热管理系统在燃油汽车热管理架构的基础之上&#xff0c;又增加了电机电控热…

【Python百日进阶-数据分析】Day228 - plotly的图表的变换

文章目录一、过滤二、分组三、聚合四、多重转换4.1 Filter and Group By4.2 Filter and Aggregate4.3 所有变换4.4 Dash中的应用一、过滤 如何通过 Plotly 在 Python 中使用过滤器。 注意 transforms在 v5 中已弃用&#xff0c;plotly将在未来版本中删除 import plotly.io as…

分享97个PHP源码,总有一款适合您

PHP源码 分享97个PHP源码&#xff0c;总有一款适合您 下面是文件的名字&#xff0c;我放了一些图片&#xff0c;文章里不是所有的图主要是放不下...&#xff0c; 97个PHP源码下载链接&#xff1a;https://pan.baidu.com/s/1OUa-rpzDK6CG8oj6BLZSTw?pwdxdt2 提取码&#xff…

上传ipa到appstore的步骤说明

上传ipa到appstore&#xff0c;首先你要有苹果开发者账号&#xff0c;一定要使用你自己的苹果开发者账号的证书打包&#xff0c;才能将ipa上传到你自己的苹果账号&#xff0c;才能提交到app store里。假如你还没有苹果开发者账号&#xff0c;或者你有证书但不是你自己账号生成的…

ES6ES6

ES8-ES8 新特性 4.1.async 和 await async和await 两种语法结合可以让异步代码像同步代码一样 4.1.1.async函数 async函数的返回值为 promise 对象&#xff0c; 2.promise 对象的结果由 asynt函数执行的返回值决定 4.1.2await表达式awaity必须写在 async 函数中 2.await 右侧…