怎么用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 -y
再npm 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); });
bagpipe
建个文件夹multi
吧,cd multi;npm init -y
再npm 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))) }
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'))