怎么用node批量下载图片

简介: 怎么用node批量下载图片

怎么用node批量下载图片


本文目标:执行脚本,可以自动请求大量图片地址,将图片下载到本地。

下载单张图片到本地

来直接动手!!! 新建个js文件,如single.js,里面放上下面的代码,然后node single.js就会看到同个文件夹下多了一个图片

let fs = require('fs')
let request = require('request')
let path = require('path')
// 下载单张图片 src是图片的网上地址 dest是你将这图片放在本地的路径 callback可以是下载之后的事}
const downloadImage = (src, dest, callback) => {
  request.head(src, (err, res, body) => {
    if (err) { console.log(err); return }
    src && request(src).pipe(fs.createWriteStream(dest)).on('close', () => {
      callback && callback(null, dest)
    })
  })
}
downloadImage('https://article-fd.zol-img.com.cn/t_s640x2000/g4/M06/06/0B/ChMly11592GIf2IZABGTyV_p7DgAAXpLwH8ztgAEZPh660.jpg', './就是这张图.jpg', (err, data) => { err ? console.log(err) : console.log(`下载成功!图片地址是:${path.resolve(data)}`) })

批量下载图片

理论上,循环上面的代码就可以批量下载图片,但是由于图片链接比较多,总是在下载到一部分图片后出现一些错误。所以批量的时候就借用一些工具。

async

建个文件夹multi吧,cd multi;npm init -ynpm i async,再建个async.js,放上下面的代码,然后node async.js就会看到同个文件夹下多了很多图片。

const async = require("async");
const request = require("request");
const fs = require("fs");
const path = require("path");
const downloadImage = (src, dest, callback) => {
  request.head(src, (err, res, body) => {
    if (err) {
      console.log(err);
      return;
    }
    src &&
      request(src)
        .pipe(fs.createWriteStream(dest))
        .on("close", () => {
          callback && callback(null, dest);
        });
  });
};
let imageLinks = [
  {
    title: "这才是未来大屏该有的样子",
    url:
      "https://article-fd.zol-img.com.cn/t_s640x2000/g1/M03/02/02/ChMljl2ENKuIV553AAKEYP9wZOQAAP23wGEctEAAoR4006.jpg"
  },
  {
    title: "智慧屏",
    url:
      "https://article-fd.zol-img.com.cn/t_s640x2000/g1/M05/01/06/ChMljV1_QwqIEEeTACmpHidBeUkAAPz4QMudwgAKak2877.jpg"
  }
];
const getSuffix = str => str.slice(str.lastIndexOf("."));
async.mapSeries(imageLinks, function(item, callback) {
  setTimeout(function() {
    var destImage = `${item.title}${getSuffix(item.url)}`;
    destImage = `./dist/${destImage}`;
    downloadImage(item, destImage, (err, data) => {
      err ? console.log(err) : console.log(path.resolve(data));
    });
    callback && callback(null, item);
  }, 100);
});

async的gitbub

bagpipe

建个文件夹multi吧,cd multi;npm init -ynpm i async,再建个bagpipe.js,放上下面的代码,然后node bagpipe.js就会看到同个文件夹下多了很多图片。

// 这里粘贴 single.js里面的代码
let Bagpipe = require('bagpipe')
// 1表示同时发出多少个请求 timeout表示多长时间下载完 这里自定义吧
let bagpipe = new Bagpipe(1, { timeout: 5000 })
let imageLinks = [{ title: '这才是未来大屏该有的样子', url: 'https://article-fd.zol-img.com.cn/t_s640x2000/g1/M03/02/02/ChMljl2ENKuIV553AAKEYP9wZOQAAP23wGEctEAAoR4006.jpg' }, { title: '智慧屏', url: 'https://article-fd.zol-img.com.cn/t_s640x2000/g1/M05/01/06/ChMljV1_QwqIEEeTACmpHidBeUkAAPz4QMudwgAKak2877.jpg' }]
const getSuffix = str => str.slice(str.lastIndexOf('.'))
for (let i = 0; i < imageLinks.length; i++) {
  let item = imageLinks[i]
  let destImage = `${item.title}${getSuffix(item.url)}`
  bagpipe.push(downloadImage, item.url, destImage, (err, data) => err ? console.log(err) : console.log(path.resolve(data)))
}

bagpipe的github

async和bagpipe都是很优秀的nodejs包,本身async功能十分强大,bagpipe使用起来简单方便,对原有的异步代码几乎不必做太多改动。因此可以根据自己喜好选择使用。

request

request很神奇,可以直接发起请求。正如上面看到的那样。这里简单说下使用方式。 任何响应都可以输出到文件流。默认是get请求。

将response写到本地文件里

const request = require('request')
const fs = require('fs')
// 直接写到文件里
request('https://www.baidu.com').pipe(fs.createWriteStream('baidu.html'))
// 也可以拿到响应体
request('https://www.baidu.com', (error, response, body) => {
  if (!error && response.statusCode === 200) {
    //   可以拿到响应体
    console.log(body)
    // 有兴趣的话 可以 npm i cheerio,cheerio可以对字符串进行类似于jquery的读取 这样能做更多的事
    /*
    const cheerio = require('cheerio')
    const $ = cheerio.load(body)
    console.log($('#btop').html())
    console.log($('#btop').attr('href'))
    */
  }
})

post

request支持application/x-www-form-urlencoded和multipart/form-data实现表单上传。

  • x-www-form-urlencoded很简单:
// 这样可以爬虫某些接口
request.post('http://service.com/upload', {form:{key:'value'}},(error, response, body) => {
  if (!error && response.statusCode === 200) {
    //   可以拿到响应体
    console.log(body)
  }
})
  • multipart/form-data也容易
var r = request.post('http://service.com/upload')
var form = r.form()
form.append('my_field', 'my_value')
form.append('my_buffer', new Buffer([1, 2, 3]))
form.append('my_file', fs.createReadStream(path.join(__dirname, 'doodle.png'))
form.append('remote_file', request('http://google.com/doodle.png'))

参考资料

目录
相关文章
|
17天前
|
JavaScript 前端开发 安全
使用 Node.js 插件给指定目录下的所有图片添加上文字水印
使用 Node.js 插件给指定目录下的所有图片添加上文字水印
71 0
|
前端开发
node express 给前端返回图片流
node express 给前端返回图片流
node express 给前端返回图片流
|
前端开发 JavaScript 数据格式
图片URL转file文件(前端+后端node.js)
图片URL转file文件(前端+后端node.js)
|
17天前
|
编解码 前端开发 JavaScript
node实战——koa实现文件下载和图片/pdf/视频预览(node后端储备知识)
node实战——koa实现文件下载和图片/pdf/视频预览(node后端储备知识)
40 1
|
17天前
|
前端开发
【Node】一键生成博客标题图片
还在为写文章时找不到标题图片而困扰吗?举个例子,CSDN的博客文章如果你不给他图片的话,那么它会按照一些默认的标签图片作为你的文章封面,例如下面这样。
32 7
|
7月前
|
编解码
node封装一个图片拼接插件
node封装一个图片拼接插件
81 0
|
9月前
|
JavaScript 前端开发
[Node] Node.js Webpack打包图片-Js-Vue
[Node] Node.js Webpack打包图片-Js-Vue
|
JavaScript 前端开发 中间件
vue3 + node 实战(实现图片操作功能)总结
作用是:这样 vite 在执行 runOptimize 的时候中会使用 rollup 对 包含的 包重新编译,将编译成符合 esm 模块规范的新的包放入 node_modules 下的.vite_opt_cache中,然后配合 resolver 对 包含的包 的导入进行处理:使用编译后的包内容代替原来 qrcanvas 的包的内容,这样就解决了 vite 中不能使用 其他js包 的问题,这部分代码在 depOptimizer.ts 里。
vue3 + node 实战(实现图片操作功能)总结
|
前端开发 中间件
node express前端 canvas操作图片 报跨域
我后台使用的是 node + express ,所以首先定位问题所在,图片是属于静态资源的,然后我们后台解析静态资源使用 express 里面的 static 中间件。所以打开对应的文档,查看对应的配置。
node express前端 canvas操作图片 报跨域
|
中间件
node 图片制作防盗链中间件
如果从自己的服务器中访问使用外链,浏览器会告诉外链方中,请求头会加一个refere 的请求头,用于标记该网页的来源服务器是哪个地址或者域名。如果是自己的服务访问自己的资源,浏览器是不会携带该请求头的或者携带的请求头和host是一样的,所以我们就可以使用referer这个浏览器所携带的特性。
node 图片制作防盗链中间件