nodejs批量下载图片的实现方法


Posted in NodeJs onMay 19, 2017

今天想获取一大批猫的图片,然后就在360流浪器搜索框中输入猫,然后点击图片。就看到了一大波猫的图片:http://image.so.com/i?q=%E7%8...,我在想啊,要是审查元素,一张张手动下载,多麻烦,所以打算写程序来实现。不写不知道,一写发现里面还是有很多道道的。

nodejs批量下载图片的实现方法

1. 爬取图片链接

因为之前也写过nodejs爬虫功能,所以觉得应该很简单,就用cheerio来处理dom啦,结果打印一下啥也没有,后来查看源代码:

nodejs批量下载图片的实现方法

发现waterfall_zoom里面空空如也,查找了一下,发现所有的数据都是写在<script>里面,然后动态加载到页面的,所以用cheerio.load到的页面里面其实没数据的。真实数据:

nodejs批量下载图片的实现方法

分析完毕,刷刷写代码:

var request = require('request');
var cheerio = require('cheerio');
var url = 'http://image.so.com/i?q=%E7%8C%AB&src=tab_www';

request(url,function(err,res,body){
  if(!err && res.statusCode === 200){
    var $ = cheerio.load(body);
    var imgList = []
    JSON.parse($('script[id="initData"]').html()).list.forEach(function(item){
      imgList.push(item.img)
    });
    console.log(imgList);
  }
});

nodejs批量下载图片的实现方法

2. 下载图片到本地

2.1 粗糙的方案

最初的思路很简单,简单的fs.createWriteStream()就能解决:

var downloadPic = function(src, dest){
  request(src).pipe(fs.createWriteStream(dest)).on('close',function(){
    console.log('pic saved!')
  })
}

使用方式:

downloadPic(imgList[0],'./catpics/1.jpg');

 nodejs批量下载图片的实现方法

成功捕获一只猫!然后写了一个循环准备捕获所有猫。然而这种方式是串行的,速度很慢!下载一大批图片要花大量时间。

2.2 使用async异步批量下载

关于async的map操作,详见:async_demo/map.js,对集合中的每一个元素,执行某个异步操作,得到结果。所有的结果将汇总到最终的callback里。与forEach的区别是,forEach只关心操作不管最后的值,而map关心的最后产生的值。

提供了两种方式:

  1. 并行执行。async.map同时对集合中所有元素进行操作,结果汇总到最终callback里。如果出错,则立刻返回错误以及已经执行完的任务的结果,未执行完的占个空位
  2. 顺序执行。async.mapSeries对集合中的元素一个一个执行操作,结果汇总到最终callback里。如果出错,则立刻返回错误以及已经执行完的结果,未执行的被忽略。

在此处:

async.mapSeries(imgList,function(item, callback){
  setTimeout(function(){
    downloadPic(item, './catpics/'+ (new Date()).getTime() +'.jpg');
    callback(null, item);
  },400);
}, function(err, results){});

注:此处使用setTimeout,是因为下载需要一定时间,在笔者较慢网速下,需要400ms的间隔能确保每张图片下载完全。

 nodejs批量下载图片的实现方法

成功捕获一批猫猫!

2.3 使用bagpipe批量

bagpipe是朴灵大大做的一个在nodejs中控制并发执行的模块。其安装和使用也比较简单:

npm install bagpipe --save

使用:

var Bagpipe = require('bagpipe');

var bagpipe = new Bagpipe(10);
var files = ['这里有很多很多文件'];
for(vari =0; i < files.length; i++){
  bagpipe.push(fs.readFile, files[i], 'utf-8',function(err, data){
    ...
  });
}

在此处:

var bagpipe = new Bagpipe(10,{timeout: 100});
for(var i = 0; i < imgList.length; i++) {
  console.log('i:'+i)
  bagpipe.push(downloadPic, imgList[i], './catpics/'+ i +'.jpg', function(err, data){
    //
   });
}

3.总结

作为一个程序员,能用程序解决就不手动解决。每一次尝都会有新的收获。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

NodeJs 相关文章推荐
在NodeJS中启用ECMAScript 6小结(windos以及Linux)
Jul 15 NodeJs
Windows 系统下设置Nodejs NPM全局路径
Apr 26 NodeJs
nodejs加密Crypto的实例代码
Jul 07 NodeJs
用NodeJS实现批量查询地理位置的经纬度接口
Aug 16 NodeJs
NodeJs读取JSON文件格式化时的注意事项
Sep 25 NodeJs
Nodejs中解决cluster模块的多进程如何共享数据问题
Nov 10 NodeJs
进阶之初探nodeJS
Jan 24 NodeJs
nodejs中解决异步嵌套循环和循环嵌套异步的问题
Jul 12 NodeJs
NodeJS父进程与子进程资源共享原理与实现方法
Mar 16 NodeJs
Nodejs 和 Electron ubuntu下快速安装过程
May 04 NodeJs
nodeJS进程管理器pm2的使用
Jan 09 NodeJs
nodejs中的异步编程知识点详解
Jan 17 NodeJs
nodejs制作爬虫实现批量下载图片
May 19 #NodeJs
详解Windows下安装Nodejs步骤
May 18 #NodeJs
nodejs+websocket实时聊天系统改进版
May 18 #NodeJs
nodejs6下使用koa2框架实例
May 18 #NodeJs
Nodejs中使用captchapng模块生成图片验证码
May 18 #NodeJs
详解使用nodeJs安装Vue-cli
May 17 #NodeJs
NodeJS创建最简单的HTTP服务器
May 15 #NodeJs
You might like
php设计模式 Command(命令模式)
2011/06/26 PHP
PHP中鲜为人知的10个函数
2014/02/28 PHP
php实现点击可刷新验证码
2015/11/07 PHP
关于PHP中协程和阻塞的一些理解与思考
2017/08/11 PHP
jquery 弹出层实现代码
2009/10/30 Javascript
基于jquery的一行代码轻松实现拖动效果
2010/12/28 Javascript
Node.js中的事件驱动编程详解
2014/08/16 Javascript
jQuery 1.9.1源码分析系列(十)事件系统之主动触发事件和模拟冒泡处理
2015/11/24 Javascript
js实现的页面矩阵图形变换特效
2016/01/26 Javascript
js纯数字逐一停止显示效果的实现代码
2016/03/16 Javascript
AngularJS入门(用ng-repeat指令实现循环输出
2016/05/05 Javascript
jquery插件autocomplete用法示例
2016/07/01 Javascript
js实现交通灯效果
2017/01/13 Javascript
激动人心的 Angular HttpClient的源码解析
2017/07/10 Javascript
Layui table 组件的使用之初始化加载数据、数据刷新表格、传参数
2017/09/11 Javascript
vue绑定的点击事件阻止冒泡的实例
2018/02/08 Javascript
vuex state及mapState的基础用法详解
2018/04/19 Javascript
深入浅析angular和vue还有jquery的区别
2018/08/13 jQuery
基于vue-cli搭建多模块且各模块独立打包的项目
2019/06/12 Javascript
vue+element实现图片上传及裁剪功能
2020/06/29 Javascript
python调用windows api锁定计算机示例
2014/04/17 Python
Python实现提取文章摘要的方法
2015/04/21 Python
浅谈Python的条件判断语句if/else语句
2019/03/21 Python
python使用MQTT给硬件传输图片的实现方法
2019/05/05 Python
Python实现分数序列求和
2020/02/25 Python
PyCharm中如何直接使用Anaconda已安装的库
2020/05/28 Python
8种常用的Python工具
2020/08/05 Python
python中pivot()函数基础知识点
2021/01/03 Python
HTML5边玩边学(2)基础绘图实现方法
2010/09/21 HTML / CSS
水务局局长岗位职责
2013/11/28 职场文书
转让协议书范本
2014/04/15 职场文书
职业生涯规划书怎么写?
2014/09/14 职场文书
期中考试复习计划
2015/01/19 职场文书
党风廉正建设个人工作总结
2015/03/06 职场文书
美术教师求职信范文
2015/03/20 职场文书
《妈妈别哭,有我在》读后感3篇
2020/01/13 职场文书