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读取memcache示例分享
Jan 02 NodeJs
nodejs分页类代码分享
Jun 17 NodeJs
nodejs实现黑名单中间件设计
Jun 17 NodeJs
浅谈NodeJS中require路径问题
May 07 NodeJs
浅析nodejs实现Websocket的数据接收与发送
Nov 19 NodeJs
使用nodejs中httpProxy代理时候出现404异常的解决方法
Aug 15 NodeJs
nodejs后台集成ueditor富文本编辑器的实例
Jul 11 NodeJs
nodejs实现的连接MySQL数据库功能示例
Jan 25 NodeJs
nodejs 简单实现动态html的方法
May 12 NodeJs
nodejs更改项目端口号的方法
May 13 NodeJs
详解微信小程序-获取用户session_key,openid,unionid - 后端为nodejs
Apr 29 NodeJs
nodejs中实现用户注册路由功能
May 20 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
让你的WINDOWS同时支持MYSQL4,MYSQL4.1,MYSQL5X
2006/12/06 PHP
从MySQL数据库表中取出随机数据的代码
2007/09/05 PHP
PHP创建桌面快捷方式的实例代码
2014/02/17 PHP
A标签中通过href和onclick传递的this对象实现思路
2013/04/19 Javascript
jquery实现的动态回到顶部特效代码
2015/10/28 Javascript
JavaScript SHA512加密算法详细代码
2016/10/06 Javascript
jQuery+正则+文本框只能输入数字的实现方法
2016/10/07 Javascript
jQuery实现表格与ckeckbox的全选与单选功能
2016/11/24 Javascript
修改 bootstrap table 默认detailRow样式的实例代码
2017/07/21 Javascript
JS简单添加元素新节点的方法示例
2018/02/10 Javascript
浅谈在vue中用webpack打包之后运行文件的问题以及相关配置方法
2018/02/21 Javascript
layui 设置table 行的高度方法
2018/08/17 Javascript
node微信开发之获取access_token+自定义菜单
2019/03/17 Javascript
使用Easyui实现查询条件的后端传递并自动刷新表格的两种方法
2019/09/09 Javascript
Python bsddb模块操作Berkeley DB数据库介绍
2015/04/08 Python
Python中用Decorator来简化元编程的教程
2015/04/13 Python
使用Python对SQLite数据库操作
2017/04/06 Python
win8下python3.4安装和环境配置图文教程
2018/07/31 Python
小白入门篇使用Python搭建点击率预估模型
2018/10/12 Python
简单了解python的一些位运算技巧
2019/07/13 Python
python 同时读取多个文件的例子
2019/07/16 Python
python爬虫开发之PyQuery模块详细使用方法与实例全解
2020/03/09 Python
增大python字体的方法步骤
2020/07/05 Python
Python如何将将模块分割成多个文件
2020/08/04 Python
python实现自动清理重复文件
2020/08/24 Python
详解python tkinter包获取本地绝对路径(以获取图片并展示)
2020/09/04 Python
澳大利亚最好的在线时尚精品店:Princess Polly
2018/01/03 全球购物
Nike澳大利亚官网:Nike.com (AU)
2019/06/03 全球购物
工程专业应届生求职信
2014/02/19 职场文书
乡镇食品安全责任书
2014/07/28 职场文书
加强作风建设心得体会
2014/10/22 职场文书
2015年五四青年节演讲稿
2015/03/18 职场文书
青年教师听课心得体会
2016/01/15 职场文书
我家女友可不止可爱呢 公开OP主题曲无字幕动画MV
2022/04/11 日漫
通过feDisplacementMap和feImage实现水波特效
2022/04/24 HTML / CSS
详解SQL报错盲注
2022/07/23 SQL Server