技术实践:快速批量下载网站图片资源实现方法

简介: 本文介绍了三种批量下载图片的方法:使用HTML页面、Node.js脚本和Bash结合Wget命令。重点推荐第三种,仅需几行命令即可高效完成下载,无需编程环境,兼容性强,适合快速批量获取网络图片资源。

前言

你好,我是喵喵侠。最近在找一套素材,看到了一个网站上的素材很实用,于是想要下载下来。一个个的下载属实太麻烦,毕竟图片有好几十张呢。一个个点速度慢,而且很容易遗漏。所以我写了一个Shell脚本来帮我解决这个问题。

思路

由于我是前端开发,我想尽量的使用前端相关的技术来做,一开始我只想了两个方案,分别是:

  • 写一个HTML的网页进行批量下载
  • 用Node.js 来实现批量下载

这两种方式都可以实现我要的功能,下面我来分享下我的实现过程。

实现过程

方案一:HTML实现

第一个方法是最简单的,只需要本地打开一个这个html页面,简单输入参数后,即可触发下载,于是我写了以下的页面:

源码如下:

<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <title>图片批量下载工具</title>
  <style>
    body { font-family: "微软雅黑", Arial, sans-serif; background: #f7f7f7; padding: 40px; }
    .container { background: #fff; border-radius: 8px; box-shadow: 0 2px 8px #0001; max-width: 480px; margin: auto; padding: 32px 24px; }
    h2 { text-align: center; color: #1684fc; }
    label { display: block; margin: 16px 0 8px 0; }
    input[type="text"], input[type="number"] {
      width: 100%; padding: 8px; border: 1px solid #ccc; border-radius: 4px;
      font-size: 16px; box-sizing: border-box;
    }
    button {
      width: 100%; padding: 12px; background: #1684fc; color: #fff;
      border: none; border-radius: 4px; font-size: 18px; cursor: pointer; margin-top: 20px;
    }
    button:active { background: #1060b0; }
    #downloadStatus { margin-top: 18px; text-align: center; color: #16c2fc; }
  </style>
</head>
<body>
  <div class="container">
    <h2>图片批量下载工具</h2>
    <label>图片URL前缀:</label>
    <input id="urlPrefix" type="text" value="https://xxx.com/webp/">
    <label>起始编号:</label>
    <input id="startNum" type="number" value="0">
    <label>结束编号:</label>
    <input id="endNum" type="number" value="77">
    <label>图片格式(如webp、jpg、png):</label>
    <input id="imgExt" type="text" value="webp">
    <button onclick="batchDownload()">批量下载</button>
    <div id="downloadStatus"></div>
    <div style="color:#888;font-size:13px;margin-top:18px;">
      <b>提示:</b>浏览器会自动下载图片到默认下载目录,无法指定文件夹。<br>
      如遇浏览器拦截,请允许多文件下载。
    </div>
  </div>
  <script>
    function batchDownload() {
      const prefix = document.getElementById('urlPrefix').value.trim();
      const start = parseInt(document.getElementById('startNum').value, 10);
      const end = parseInt(document.getElementById('endNum').value, 10);
      const ext = document.getElementById('imgExt').value.trim().replace(/^\./, '');
      const status = document.getElementById('downloadStatus');
      if (isNaN(start) || isNaN(end) || start > end) {
        status.innerText = '编号输入有误!';
        return;
      }
      status.innerText = '正在下载,请稍候...';
      let count = 0;
      let total = end - start + 1;
      let fail = 0;
      for (let i = start; i <= end; i++) {
        const url = `${prefix}${i}.${ext}`;
        fetch(url)
          .then(res => {
            if (!res.ok) throw new Error('下载失败: ' + url);
            return res.blob();
          })
          .then(blob => {
            const a = document.createElement('a');
            a.href = URL.createObjectURL(blob);
            a.download = `${i}.${ext}`;
            document.body.appendChild(a);
            a.click();
            a.remove();
            count++;
            if (count + fail === total) {
              status.innerText = fail === 0 ? '全部下载完成!' : `下载完成,${fail} 个文件失败`;
            }
          })
          .catch(e => {
            fail++;
            if (count + fail === total) {
              status.innerText = fail === 0 ? '全部下载完成!' : `下载完成,${fail} 个文件失败`;
            }
          });
      }
    }
  </script>
</body>
</html>

这样可能会有个问题,当本地或者自己服务器部署的这个页面,访问对方网站服务器资源时,可能会触发跨域。

所以这种方法不是很好,于是我做了新的探索。

方法二:Node.js实现

如果你的电脑安装了Node.js,就可以用这个方法,这样的好处是不存在跨域的问题,用node内置的模块就能实现功能。

源码如下:

const fs = require('fs');
const path = require('path');
const https = require('https');
const http = require('http');
const readline = require('readline');
// 获取用户输入
const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout
});
function ask(question) {
  return new Promise(resolve => rl.question(question, resolve));
}
(async () => {
  const urlPrefix = await ask('请输入图片URL前缀(如 https://xxx/images/):');
  const startNum = parseInt(await ask('请输入起始编号(如 0):'), 10);
  const endNum = parseInt(await ask('请输入结束编号(如 77):'), 10);
  const ext = await ask('请输入图片格式(如 webp):');
  const saveDir = './我的下载图片';
  if (!fs.existsSync(saveDir)) fs.mkdirSync(saveDir);
  let success = 0, fail = 0;
  function download(url, dest) {
    return new Promise((resolve, reject) => {
      const mod = url.startsWith('https') ? https : http;
      mod.get(url, res => {
        if (res.statusCode !== 200) {
          reject(new Error('状态码: ' + res.statusCode));
          return;
        }
        const file = fs.createWriteStream(dest);
        res.pipe(file);
        file.on('finish', () => file.close(resolve));
      }).on('error', reject);
    });
  }
  for (let i = startNum; i <= endNum; i++) {
    const url = `${urlPrefix}${i}.${ext.replace(/^\./, '')}`;
    const dest = path.join(saveDir, `${i}.${ext.replace(/^\./, '')}`);
    try {
      // eslint-disable-next-line no-await-in-loop
      await download(url, dest);
      console.log(`下载成功: ${i}.${ext}`);
      success++;
    } catch (e) {
      console.log(`下载失败: ${i}.${ext} (${e.message})`);
      fail++;
    }
  }
  console.log(`\n下载完成,成功 ${success} 个,失败 ${fail} 个。图片保存在 ${saveDir} 文件夹。`);
  rl.close();
})();

输入好参数后,可以看到图片下载完成。

需要注意的是,我写的这个版本都需要手动输入参数,不输入直接回车,就会下载失败。

这个方法也还不错,只是依赖Node.js环境,后面发现还有更简单的方法。

方法三:Bash + Wget实现(推荐)

我用的是macOS,自带Bash环境,如果你是Windows,也可以用Git Bash或者WSL中来执行Wget命令。

这个方法就简单多了,5 行命令搞定!

mkdir 我的下载图片
cd 我的下载图片
for i in {0..77}; do
  wget https://xxxx.com/images/xxx/webp/$i.webp
done

总结

下载图片资源这个工具还挺实用的,可以解决批量下载的问题。如果你有多个图片的URL,也可以用类似这样的思路去实现自己的小工具。我这个图片资源正好是按照数字的索引来的,所以实现起来会更简单一些。如果你有更好的实现思路,欢迎评论区分享。

目录
相关文章
|
4天前
|
自然语言处理 前端开发 Windows
推荐一款很好用的VSCode变量翻译插件
本文介绍VSCode插件“var-translate-en”,可一键将中文翻译为英文并转为小驼峰等命名格式,支持百度、腾讯、阿里等翻译服务。通过简单配置与快捷键设置,提升变量命名效率,解决命名难题。
92 0
|
4天前
|
安全 网络安全 开发工具
解决 Host key verification failed 报错的三种方法(含 SSH 安全建议)
本文由喵喵侠撰写,详解Git提交时常见报错“Host key verification failed”的成因与解决方案。当SSH密钥变更或服务器重装系统时,本地记录的主机密钥会失效,导致连接被拒。文章提供三种解决方法:使用`ssh-keygen -R`删除旧密钥、手动编辑`known_hosts`文件,或临时禁用严格检查(不推荐生产环境)。同时强调安全建议:确认服务器状态、核对密钥指纹、启用`VerifyHostKeyDNS`防范中间人攻击。帮助开发者快速定位问题,保障代码提交顺畅。
100 0
|
4天前
|
移动开发 前端开发 JavaScript
uni-app实战案例:实现H5页面麦克风权限获取与录音功能
本文介绍如何在uni-app的H5页面中实现麦克风权限获取与录音功能,涵盖音频流转换为Blob、Base64及文件下载的完整方案,助力前端语音交互开发。
115 0
|
4天前
|
JSON 开发工具 数据安全/隐私保护
Windows 上值得推荐的软件(第三弹)
本文推荐两款高效实用的Windows软件:Bandizip,支持智能自动解压,解决文件混乱问题;FastGestures,通过鼠标手势大幅提升操作效率,尤其适合开发者优化工作流。
47 0
|
1天前
|
人工智能 小程序 JavaScript
uni-app微信小程序相机组件二次拍照白屏问题的排查与解决
本文分享了在uni-app开发微信小程序时,因状态管理不当导致拍照后图片不显示的bug排查过程。问题根源在于删除照片时将变量设为“#”(truthy值),导致条件渲染逻辑错误。通过彻底清空相关状态并遵循最佳实践,最终解决问题。
20 2
|
1天前
|
JavaScript 前端开发 iOS开发
NVS:一款简洁高效的 Node.js 版本管理工具
本文由前端开发者喵喵侠分享,介绍轻量级Node.js版本管理工具nvs的使用方法。涵盖Windows安装、常用命令(如add、link、use、ls、rm)、全局与局部版本切换技巧,并详细说明macOS下卸载nvs的完整步骤。相比nvm,nvs在Windows上体验更稳定,操作简洁高效,适合多项目开发场景。
33 1
|
1天前
|
前端开发 JavaScript iOS开发
Volta:一款优秀的前端开发 JavaScript 项目管理器
前端开发者喵喵侠分享使用 Volta 管理 Node.js 版本的实战经验。Volta 可跨平台统一管理 Node、npm、pnpm 等工具版本,支持在 `package.json` 中锁定依赖,实现项目级环境自动切换,尤其解决了 Windows 下 nvm/nvs 的兼容问题,提升团队协作效率。
24 1
|
4天前
|
JavaScript 前端开发 开发者
如何防止Vue页面局部元素滚动时,页面整体滚动?
本文由喵喵侠分享,针对Vue中列表组件滚动时触发页面整体滚动的问题,分析了`e.stopPropagation()`无法阻止默认行为的原因,并提出使用`e.preventDefault()`来禁止浏览器默认滚动。同时扩展介绍了该方法在阻止表单提交、链接跳转等场景的应用,以及与`return false`的区别,帮助开发者更精准地控制事件行为。
34 1
|
4天前
|
JavaScript 搜索推荐 测试技术
为什么要使用 Git 作为代码版本管理工具?
本文记录了一次Vue2项目打包卡在最后一步的排查过程。作者发现测试环境打包被阻塞,通过回退配置定位到`code-inspector-plugin`插件及`.env.test`中`NODE_ENV=production`的错误配置,修正后问题解决。
24 1
|
1天前
|
前端开发 程序员 API
作为前端开发,分享下我在编程中的好习惯
前端开发喵喵侠分享多年实战总结的8个编程好习惯:写前先思考、注释重“为什么”、规范命名、代码自检、写文档、Git提交规范化、表单提示友好化、果断删除无用代码。习惯决定代码质量,写出半年后自己仍能读懂的代码,才是成熟的开始。
16 0

热门文章

最新文章