撸了几行骚代码,解放了双手

news/2025/1/3 5:32:55/

大家好,我是二哥呀~

作为一名技术博主,经常需要把同一份 MD 文件同步到不同的博客平台,以求获得更多的曝光,从而帮助到更多的小伙伴——瞧我这“达则兼济天下”的雄心壮志。像 CSDN 和掘金这两个博客平台都有自己的外链图片解析功能。

当我把 MD 源文档复制到 CSDN 或者掘金的编辑器中,它们会自动地帮我把外链转成内链,这样我就不用再重新上传图片,也不需要配置自己的图床了,否则图片会因为防盗链的原因显示不出来。

举个例子,现在有这样一段 MD 文档,里面有一张图片。![](https://upload-images.jianshu.io/upload_images/1179389-0155ada60932b724.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

把上面的 MD 文档复制到掘金编辑器的时候,就会出现「图片解析中…」!但会一直卡在这里,再也解析不下去了。

这是因为图片加了防盗链,掘金这么牛逼的社区在解析的时候也会失败。CSDN 的转链功能更牛逼一点,基本上可以无视防盗链。

还有一些博客平台是没有转链功能的,比如说二哥的静态小破站《Java 程序员进阶之路》。怎么办呢?我一开始的解决方案是:

  • 先将图片手动一张张下载到本地
  • 再将本地图片上传到 GitHub 指定的仓库
  • 修改 MD 文档中的图片链接,使用 CDN 加速服务

这样就能解决问题,但是需要手动去做这些重复的动作,尤其遇到一篇文章有二三十张图片的时候就很烦。这有点丧失我作为程序员的尊严啊!

首先要解决的是图片下载的问题,可以利用爬虫技术:爬虫爬得早,局子进的早。

二、关于 Java 爬虫

Java 爬虫的类库非常多,比如说 crawler4j,我个人更喜欢 jsoup,它更轻量级。jsoup 是一款用于解析 HTML 的 Java 类库,提供了一套非常便捷的 API,用于提取和操作数据。

官网地址:https://jsoup.org/

jsoup 目前在 GitHub 上已经收获 9.3k+ 的 star,可以说是非常的受欢迎了。

jsoup 有以下特性:

  • 可以从 URL、文件或者字符串中抓取和解析
  • 可以使用 DOM 遍历或者 CSS 选择器查找和提取数据
  • 可以操作 HTML 元素、属性和文本
  • 可以输出整洁的 HTML

三、实战 jsoup

第一步,添加 jsoup 依赖到项目中

<dependency><!-- jsoup HTML parser library @ https://jsoup.org/ --><groupId>org.jsoup</groupId><artifactId>jsoup</artifactId><version>1.14.3</version>
</dependency>

第二步, 获取网页文档

就拿二哥之前发表的一篇文章《二哥的小破站终于上线了,颜值贼高》来举例吧。通过以下代码就可以拿到网页文档了。

Document doc = Jsoup.connect("https://blog.csdn.net/qing_gee/article/details/122407829").get();
String title = doc.title();

Jsoup 类是 jsoup 的入口类,通过 connect 方法可以从指定链接中加载 HTML 文档(用 Document 对象来表示)。

第三步,获取图片节点

再通过以下代码可以获取文章所有的图片节点:

Elements images = doc.select(".article_content img[src~=(?i)\\.(png|jpe?g|gif)]");
for (Element image : images) {System.out.println("src : " + image.attr("src"));
}

输出结构如下所示:

四、下载图片

拿到图片的 URL 地址后,事情就好办了,可以直接通过 JDK 的原生 API 下载图片到指定文件夹。

String downloadPath = "/tobebetterjavaer-beian-";
for (Element image : images) {URL url = new URL(image.attr("src"));InputStream inputStream = url.openStream();OutputStream outputStream = new FileOutputStream(downloadPath + i + ".png");byte[] buffer = new byte[2048];int length = 0;while ((length = inputStream.read(buffer)) != -1) {outputStream.write(buffer, 0, length);}
}

如果想加快节奏的话,可以把上面的代码封装一下,然后开个多线程,简单点的话,可以每张图片起一个线程,速度杠杠的。

new Thread(new MyRunnable(originImgUrl, destinationImgPath)).start()

五、使用 CDN 加速图片

图片下载到本地后,接下来的工作就更简单了,读取原 MD 文档,修改图片链接,使用 CDN 进行加速。我的图床采用的是 GitHub+jsDelivr CDN 的方式,不过由于 jsDelivr 的国内节点逐渐撤离了,图片在某些网络环境下访问的时候还是有点慢,后面打算用 OSS+CDN 的方式,更靠谱一点。

读取文件可以借助一下 hutool 这款 GitHub 上开源的工具类库,省去很多繁琐的 IO 操作。

官网:https://hutool.cn/

第一步,将 hutool 添加到 pom.xml 文件中

<dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.7.20</version>
</dependency>

第二步,按照行读取 MD 文件,需要用到 hutool 的 FileReader 类:

FileReader fileReader = FileReader.create(new File(docPath +fileName),Charset.forName("utf-8"));
List<String> list = fileReader.readLines();

第三步,通过正则表达式来匹配是否有需要替换的图片标签,MD 中的图片标记关键字为 ![]()

![](https://upload-images.jianshu.io/upload_images/1179389-71c15111525af102.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

如果匹配到,就替换为 jsDelivr CDN 链接的地址,写文件时需要用到 hutool 的FileWriter 类。

FileWriter writer = new FileWriter(docPath + fileName);
for (String line : list) {Matcher m = pattern.matcher(line);if (m.matches()) {writer.append("![](" + imgCdnPre +  num + imgSuffix +")\n");} else {writer.append(line+"\n");}
}
writer.flush();

到此为止,整个代码的编写工作就告一段落了。很简单,两个类库,几行代码就搞定了!

转换前的 MD 文件如下所示:

运行代码转换后,发现图片地址已经变成 jsDelivr CDN 图库了。

使用 GitHub 桌面版把图片和 MD 文档提交到 GitHub 仓库后,就可以看到图片已经加载完成可以访问了。

六、一点小心得

不得不说,懂点技术,还是非常爽的。撸了几行代码,解放了双手,可以干点正经事了(狗头)。

这不,重新把《Java 程序员进阶之路》的小破站整理排版了一下,新增了不少优质的内容。学习 Java 的小伙伴可以开卷了,有需要增加的内容也欢迎提交 issue 啊!

再次感谢各位小伙伴的厚爱,我也会一如既往地完善这个专栏,我们下期见~


http://www.ppmy.cn/news/334605.html

相关文章

加油呀 小老弟

1.nn.ModuleList() nn.ModuleList() is a container class容器类&#xff1f; in PyTorch that can be used to store a list of nn.Module objects. It is similar to the built-in Python list type, but has additional functionality specific to PyTorch modules. One …

.NET开源工具类库:Masuit.Tools

【开源框架】| 通用工具类库 这是恰童鞋骚年的第223篇原创文章 本文介绍一个我的同事【懒得勤快】&#xff08;人称勤快哥&#xff0c;我们叫他骚哥&#xff09;写的一个.NET开源工具类库项目&#xff0c;包含一些常用的操作类&#xff0c;大都是静态类&#xff0c;加密解密&am…

互联网赚钱骚操作,真的太骚了

今天是周六我们来聊一个比较俗的事&#xff1a;互联网赚钱的骚操作。 如何利用互联网热门游戏&#xff0c;空手套白狼日入上千。 全篇看完你一定会被其中的骚操作&#xff0c;刷新认识。 这也是痴海会写本文的目的&#xff1a;开拓大家互联网商业视野。 技术人眼里不应该只有技…

bash编程(马哥)

bash基础特性&#xff1a; 命令行展开&#xff1a;~&#xff0c;{} 命令别名&#xff1a;alias&#xff0c;unalias 命令历史&#xff1a;history 命令和路径补全&#xff1a;$PATH glob通配符&#xff1a;*&#xff0c;?&#xff0c;[]&#xff0c;[^]&#xff0c; 快捷键&am…

笑死!俩美女路边直播拉路人点歌,结果拉来了黄仁勋,全程魔性互动

&#x1f447;&#x1f447;关注后回复 “进群” &#xff0c;拉你进程序员交流群&#x1f447;&#x1f447; 来源丨新智元 https://mp.weixin.qq.com/s/07xW49EQNf3VIXkUQ8C4Lw 新智元报道 编辑&#xff1a;David 【新智元导读】两位人美歌甜的宝岛妹子主播&#xff0c;街头…

【C语言】那些优秀代码里的骚操作(持续更新…)

【C语言】那些优秀代码里的骚操作&#xff08;持续更新…&#xff09; 1、联合体union的妙用2、#include的本质是什么&#xff1f;3、脱裤子放屁的do{ }while(0)4、一个成熟的代码要学会自己写函数5、…… 语言这个东西&#xff0c;其实没有奇技淫巧&#xff0c;凡是可以写出来…

算法17: 删除排序链表中的重复元素(升序链表去重)

一、需求 给定一个已排序的链表的头 head &#xff0c; 删除所有重复的元素&#xff0c;使每个元素只出现一次 。返回 已排序的链表 。 示例 1&#xff1a; 输入&#xff1a;head [1,1,2] 输出&#xff1a;[1,2] 示例 2&#xff1a; 输入&#xff1a;head [1,1,2,3,3] 输出…

Vue中如何进行数据筛选与搜索功能实现

Vue中如何进行数据筛选与搜索功能实现 在Vue应用中&#xff0c;数据筛选和搜索是常见的需求。本文将介绍如何在Vue中进行数据筛选和搜索功能的实现&#xff0c;包括基于原生JavaScript的筛选和搜索、基于Lodash库的筛选和搜索、以及基于Vue插件的筛选和搜索。 基于原生JavaScr…