学以致用 使用OkHttp批量下载小姐姐图片
最近手机上没啥资源了,准备再高一些图片,之前的那个资源网站被我人工扒光了。那个网站还好一点,一页面大概会有5张图片。我可以使用chrome上的插件Fatkun批量下载单页面上的图片。
但这次的网站 www.itmtu.com 一页居然只有1张图片还是全尺寸展示了,妈耶。。。。如果一个套图有100张图片我岂不是要打开一百个网页。。。
而且这个网站屏蔽了右击菜单,下载需要开会员。
这个我能接受?果然F12,还好无异常,有些变态的网站会再在F12的时候清空document,这个时候就只能注入js解锁了。
我随便打开了一个图片网站,F12-> network 可以看到图片相关的请求并拿到图片地址
http://img.itmtu.com/mm/s/slct/x/x.061/0001.jpg
然后我dia
然后我点击下一页查看第二张图片的地址http://img.itmtu.com/mm/s/slct/x/x.061/0002.jpg
我们可以看到图片路径是有规律的,只是文件名就是串四位数字不够用0补齐,我试着改成了http://img.itmtu.com/mm/s/slct/x/x.061/0003.jpg
浏览器地址栏输入,回车,发现能够打开。
这个时候,问题就很简单了,循环替换下图片路径中文件名上的数字批量下载即可。这样就能拿到网站的套图了。
因为我不会python,shell脚本也不太会,所以只能拿起自己的老本行用java写个批量下载的工具类。正好刚刚学习了okhttp,可以练练手。
好,首先我们打开百度,搜索关键词【okhttp 下载文件】,巴拉巴拉猛操作,得到了成品的okhttp下载文件util类。那么我们看看这个工具类里有什么内容。
1.监听器
给的代码里定义了一个监听器接口,主要用于自定义处理一些下载事件,当然你可以不写,硬编码也不会有人打你的啦,反正自己写着玩。
public interface OnDownloadListener { /** * 下载成功之后的文件 */ void onDownloadSuccess(File file); /** * 下载进度 */ void onDownloading(int progress); /** * 下载异常信息 */ void onDownloadFailed(Exception e); }
2.文件下载核心实现方法
代码有点长 说明内容我就直接写代码的注释上了。没写过不知道怎么写,但是看肯定看的懂。
/** * @param url 下载连接 * @param destFileDir 下载的文件储存目录 * @param destFileName 下载文件名称 * @param listener 下载监听 */ public void download(final String url, final String destFileDir, final String destFileName, final OnDownloadListener listener) { // 构建一个非常基本的request,只有一个url不带任何设置和参数 Request request = new Request.Builder() .url(url) .build(); //异步请求 okHttpClient.newCall(request).enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { // 下载失败监听回调 listener.onDownloadFailed(e); } @Override public void onResponse(Call call, Response response) throws IOException { InputStream is = null; // 2Kb的小缓存 byte[] buf = new byte[2048]; int len = 0; FileOutputStream fos = null; //储存下载文件的目录 File dir = new File(destFileDir); if (!dir.exists()) { dir.mkdirs(); } File file = new File(dir, destFileName); try { // 获取响应的字节流 这个时候 请求的数据还没返回接受 is = response.body().byteStream(); // 获取下下载文件的大小 用于判断下载进度百分比 long total = response.body().contentLength(); // 创建一个文件输出流用于写文件 fos = new FileOutputStream(file); // 文件已写入长度 long sum = 0; while ((len = is.read(buf)) != -1) { fos.write(buf, 0, len); sum += len; int progress = (int) (sum * 1.0f / total * 100); //下载中更新进度条 listener.onDownloading(progress); } fos.flush(); //下载完成 listener.onDownloadSuccess(file); } catch (Exception e) { listener.onDownloadFailed(e); } finally { try { if (is != null) { is.close(); } if (fos != null) { fos.close(); } } catch (IOException e) { } } } }); }
3.构建一个 OkHttpClient
这个网站访问的比较慢,所以设置超长的180s超时事件 并使用了一个本地代理加速下载。
OkHttpClient okHttpClient = new OkHttpClient.Builder() .callTimeout(180, TimeUnit.SECONDS) .proxy(new Proxy(Proxy.Type.HTTP, new InetSocketAddress("127.0.0.1", 1081))) .build();
4.监听接口实现类
没啥东西,只是打印一些数据
private static void downFile(String url, String name) { DownloadUtil.get().download(url, "E:\\4\\", name + ".jpg", new DownloadUtil.OnDownloadListener() { @Override public void onDownloadSuccess(File file) { System.out.println("success"); } @Override public void onDownloading(int progress) { // System.out.println(progress + ""); } @Override public void onDownloadFailed(Exception e) { //下载异常进行相关提示操作 System.err.println(e.getMessage()); } }); }
5.主方法
循环体的69表示套图有69张图片,循环拼凑出网站的图片路径并调用下载
public static void main(String[] args) throws InterruptedException { for (int i = 1; i <= 69; i++) { String name = ""; if (i < 10) { name = "00" + i; } else if (i < 99) { name = "0" + i; } else { name = "" + i; } downFile("http://img.itmtu.com/mm/s/slct/alpha/alpha.008/0" + name + ".jpg", name); } }