记一次SMMS图床照片导出(用编程思维解决问题)
摘要
由于最近发现此前一直使用的图床SM.MS图床国内由于某些原因已经不能访问了,并更换了一个给国内使用的域名,导致此前上传的图片全部不能访问。为了图片稳定性,”斥巨资“购买了阿里云OSS作为图床,想着把图片转移到阿里云OSS以此来恢复博客文章中引用的图片,但事与愿违,SM.MS并未提供导出备份的功能,所以本文记录一下用编程思维解决的问题的思路。
寻找方法
1、登录SM.MS后台,查看图片列表
没问题,图片都还在,因为使用了SM.MS为国内提供的专用域名smms.app,故这里不用代理就能直接访问。
2、随机打开一张图片
好家伙,直接不显示,然后打开代理,图片成功加载
既然可以加载图片,那直接右键保存就可以了,但是问题来了,图片那么多,这得搞到什么时候。
3、使用爬虫自动化下载图片
再次回到列表,F12查看元素
看着确实很好爬,但突然想到应该还有更简单的办法,于是打开网络,看他加载页面时的接口请求
确实是通过接口请求拿到的后台数据,这就更容易了。但还是麻烦了,想到之前在Typora配置SM.MS图床的时候,需要配置一个授权Token密钥,人家是怎么对接实现的呢?莫不是有个开发者文档吧。随便查了一下还真有...
4、使用Postman调用接口测试
按照文档添加请求头授权和内容类型
输入请求接口地址,page参数
ok!接口调用成功,按页获取的,那传个大一点的页数试试
data数组为空,那我就可以从第一页开始依次请求,知道data为空时停止即可。
接下来就很简单了,只需写个程序,使用Get请求该接口,从返回的数据中拿到图片Url然后打开代理,一股脑全给它下载保存即可。
代码实现
1、请求获取到图片列表信息
这里就直接使用HttpWebRequest
,HTTP请求推荐使用RestSharp
2、因为存在多页的情况,故使用递归
每请求成功一次,page+1继续调用自己,直到请求的Data为0,表示已经没数据了
并且把每次请求的数据添加到队列,这里我简单实现了个图片队列
3、实现图片队列
private static Queue<PicInfo> picQueue = new Queue<PicInfo>(); //图片队列
/// <summary>
/// 入队
/// </summary>
/// <param name="picUrl"></param>
/// <param name="picName"></param>
private static void PicEnqueue(string picUrl, string picName)
{
lock (picQueue)
{
picQueue.Enqueue(new PicInfo { PicUrl = picUrl, FileName = picName });
Monitor.Pulse(picQueue);
}
}
/// <summary>
/// 出队
/// </summary>
/// <returns></returns>
public static PicInfo PicDequeue()
{
lock (picQueue)
{
if (picQueue.Count == 0)
{
Monitor.Wait(picQueue);
if (picQueue.Count == 0)
{
return null;
}
}
return picQueue.Dequeue();
}
}
Tips:多线程下最好加个锁保护下,也可使用线程安全的队列 ConcurrentQueue
4、开启一个线程用于从队列取出链接并下载
就是如此简单,因代码是一次性的,没有较为严格的去处理逻辑,能Run就行~~~
效果
结语
编程既是一个饭碗,一个事业,也是一门手艺,又或只是一个工具,语言也不分好坏,在合适的场景使用正确的工具就好,学会处理事情的思维更重要。