微博图床挂了!

简介:

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

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

💡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 这样也也就也可以饶过限制🚫)所以就看不到图片了。

解决问题

解释完原理之后我们发现,其实只要想办法在自己的个人站点中设置好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写了。

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

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

获取博客文件夹下的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());
    }
});

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

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

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

相关实践学习
对象存储OSS快速上手——如何使用ossbrowser
本实验是对象存储OSS入门级实验。通过本实验,用户可学会如何用对象OSS的插件,进行简单的数据存、查、删等操作。
相关文章
|
存储 安全 对象存储
手把手教你搭建阿里云图床(PicGo+Typora+阿里云OSS),新手小白一看就会
本文详细介绍了怎样帮助新手小白从注册,购买阿里云OSS,到一步一步配置OSS做为图床,和PicGo、Typora软件连接,配置好关联之后,在使用Typora写文章时,如果需要插入图片,只需要将图片复制粘贴到Typora的编辑区域,就会自动通过PicGo上传到指定图床,自动复制外网能访问的URL并展示,简直不要太方便,极大的解决了编辑文章时复制处理图片链接的痛点。
15852 16
手把手教你搭建阿里云图床(PicGo+Typora+阿里云OSS),新手小白一看就会
|
算法 测试技术 定位技术
数据结构与算法——DFS(深度优先搜索)
数据结构与算法——DFS(深度优先搜索)
|
IDE 开发工具 C++
VS2015+Qt5.9.8编译报错:error MSB6006: “cmd.exe”已退出,代码为 2
VS2015+Qt5.9.8编译报错:error MSB6006: “cmd.exe”已退出,代码为 2
3825 0
|
4月前
|
存储 人工智能 自然语言处理
2026年阿里云新老用户最新优惠活动:云服务器活动、免费试用活动、AI产品活动参考
阿里云2026新老用户优惠活动涵盖三大板块。云服务器方面,轻量应用服务器低至38元/年,经济型e实例99元/年,u1实例199元/年,限时限量抢购。免费试用方面,新老用户可领最高200元试用点,AI产品免费提供7000万+大模型tokens及30+款产品体验,140+云产品最长12个月免费试用。AI产品方面,百炼Token Plan支持多模型切换、多档套餐;HappyHorse视频生成模型限时8折;OpenClaw一键部署低至9.9元起。此外还提供折扣券、学生无门槛券、算力补贴等多类优惠券,整体以"普惠基础设施+零成本体验+智能化赋能"策略,全面降低上云与用AI门槛。
2026年阿里云新老用户最新优惠活动:云服务器活动、免费试用活动、AI产品活动参考
|
3月前
|
缓存 弹性计算 应用服务中间件
高端网站搭建:Nginx 反向代理与动静分离架构配置详解
在现代企业级 Web 架构中,Nginx 凭借其极低的内存消耗和超强的高并发处理能力,成为了不可或缺的流量网关。特别是在阿里云 ECS 实例搭配 Alibaba Cloud Linux 3 的环境下,Nginx 能够充分利用操作系统的网络栈优化,实现惊人的吞吐量。 本文将详细介绍如何配置 Nginx 的反向代理与动静分离,将静态资源请求与动态接口请求完美剥离,从而大幅提升网站的整体响应速度。
|
3月前
|
人工智能 定位技术 SEO
AI推荐了我,为什么成交还是零? ——GEO效果归因与ROI计算的科学方法
2026年,企业面临AI曝光高但转化低的困局:品牌被AI频繁提及,却难追踪到店与签约。根源在于传统归因失效——68%用户在1–7天后通过品牌搜索成交,无点击痕迹。本文首创“GEO三层归因模型”(L1直接点击、L2品牌搜索、L3认知调研),实现从“看见”到“成交”的精准量化,助力GEO投入真正上账。(239字)
|
运维 容灾 安全
国网安徽电力与阿里云联合完成行业首个全场景容灾演练
在安徽合肥的一座不起眼的数据中心里,一场没有硝烟的“战役”悄然打响。这不是一次普通的系统升级,而是一场关乎全省电网稳定运行的关键演练——这是一场关于数据、系统、故障和时间的较量,将验证电力系统背后的数据中心在碰到故障时,是否能够做到“不停电、不掉线”。 这场演练的主角,是我们身边默默守护万家灯火的电力人——国网安徽电力以及背后的技术团队,大家的目标是在极端情况下保障电网云平台稳定运行,确保每一台服务器、每一套业务系统“永不宕机”。这次演练,不仅是加速构建新型电力系统、增强电网“灵活可靠”的一次探索,也是能源电力行业迈向智能化、数字化过程中的一次真实实践。
601 11
|
IDE PHP 开发工具
除了Xdebug,还有哪些常用的PHP调试工具?
这些调试工具各有特点,开发者可以根据自己的需求和习惯选择适合的工具。在实际开发中,结合多种工具的使用往往能够更全面、更深入地进行调试,提高开发效率和代码质量。同时,随着技术的不断发展,新的调试工具也在不断涌现,开发者需要保持学习和关注,以便及时掌握最新的调试技术和工具。
650 1
|
JavaScript 前端开发 API
低代码+阿里云部署版 DeepSeek,10 分钟速成编剧大师
阿里云部署版DeepSeek重磅发布,钉钉宜搭低代码平台已首发适配,推出官方连接器。用户可轻松调用DeepSeek R1、V3及蒸馏系列模型。通过宜搭低代码技术,结合DeepSeek大模型,仅需10分钟即可制作编剧大师应用。
1897 20
|
网络协议 数据安全/隐私保护 网络架构

热门文章

最新文章