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中使用monk访问mongodb
Jul 06 NodeJs
Nodejs中的this详解
Mar 26 NodeJs
浅谈Nodejs应用主文件index.js
Aug 28 NodeJs
nodejs入门教程四:URL相关模块用法分析
Apr 24 NodeJs
理解nodejs的stream和pipe机制的原理和实现
Aug 12 NodeJs
nodejs实现截取上传视频中一帧作为预览图片
Dec 10 NodeJs
nodejs基于WS模块实现WebSocket聊天功能的方法
Jan 12 NodeJs
NodeJS模块与ES6模块系统语法及注意点详解
Jan 04 NodeJs
nodejs分离html文件里面的js和css的方法
Apr 09 NodeJs
nodejs nedb 封装库与使用方法示例
Feb 06 NodeJs
nodeJs项目在阿里云的简单部署
Nov 27 NodeJs
分享node.js实现简单登录注册的具体代码
Apr 26 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 HTML JavaScript MySQL代码如何互相传值的方法分享
2012/09/30 PHP
通过PHP简单实例介绍文件上传
2015/12/16 PHP
Yii框架批量插入数据扩展类的简单实现方法
2017/05/23 PHP
tp框架(thinkPHP)实现三次登陆密码错误之后锁定账号功能示例
2018/05/24 PHP
动态刷新 dorado树的js代码
2009/06/12 Javascript
JQuery 操作select标签实现代码
2010/05/14 Javascript
Javascript学习笔记之 函数篇(三) : 闭包和引用
2014/11/23 Javascript
jQuery中outerWidth()方法用法实例
2015/01/19 Javascript
Bootstrap入门书籍之(五)导航条、分页导航
2016/02/17 Javascript
Node.js返回JSONP详解
2016/05/18 Javascript
jQuery+CSS实现简单切换菜单示例
2016/07/27 Javascript
一步一步封装自己的HtmlHelper组件BootstrapHelper(三)
2016/09/14 Javascript
微信小程序模板之分页滑动栏
2017/02/10 Javascript
javascript高仿热血传奇游戏实现代码
2018/02/22 Javascript
vue中rem的配置的方法示例
2018/08/30 Javascript
浅谈Vue数据响应
2018/11/05 Javascript
nodejs基础之常用工具模块util用法分析
2018/12/26 NodeJs
简单实现vue中的依赖收集与响应的方法
2019/02/18 Javascript
JS异步执行结果获取的3种解决方式
2019/02/19 Javascript
开发中常用的25个JavaScript单行代码(小结)
2019/06/28 Javascript
在Python的框架中为MySQL实现restful接口的教程
2015/04/08 Python
简单总结Python中序列与字典的相同和不同之处
2016/01/19 Python
Python实现树莓派WiFi断线自动重连的实例代码
2017/03/16 Python
Python 中开发pattern的string模板(template) 实例详解
2017/04/01 Python
Python使用字典实现的简单记事本功能示例
2019/08/15 Python
Pytorch卷积层手动初始化权值的实例
2019/08/17 Python
Python 如何优雅的将数字转化为时间格式的方法
2019/09/26 Python
在Ubuntu 20.04中安装Pycharm 2020.1的图文教程
2020/04/30 Python
Ellos丹麦:时尚和服装在线
2016/09/19 全球购物
华为慧通笔试题
2016/04/22 面试题
工业自动化专业毕业生推荐信
2013/11/18 职场文书
英语专业职业生涯规划范文
2014/03/05 职场文书
乡镇爱国卫生月活动总结
2014/06/25 职场文书
2014年民主评议党员个人总结
2014/09/24 职场文书
十八大宣传标语
2014/10/09 职场文书
小学校本教研总结
2015/08/13 职场文书