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与Mysql的交互示例代码
Aug 18 NodeJs
基于NodeJS的前后端分离的思考与实践(四)安全问题解决方案
Sep 26 NodeJs
浅谈Nodejs观察者模式
Oct 13 NodeJs
Nodejs实现短信验证码功能
Feb 09 NodeJs
详解nodejs爬虫程序解决gbk等中文编码问题
Apr 06 NodeJs
win系统下nodejs环境安装配置
May 04 NodeJs
利用nodeJs anywhere搭建本地服务器环境的方法
May 12 NodeJs
nodejs取得当前执行路径的方法
May 13 NodeJs
nodejs中用npm初始化来创建package.json的实例讲解
Oct 10 NodeJs
如何让Nodejs支持H5 History模式(connect-history-api-fallback源码分析)
May 30 NodeJs
nodejs中各种加密算法的实现详解
Jul 11 NodeJs
NodeJS开发人员常见五个错误理解
Oct 14 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
判断多个元素(RADIO,CHECKBOX等)是否被选择的原理说明
2009/02/18 Javascript
利用毫秒减值计算时长的js代码
2013/09/22 Javascript
JavaScript中读取和保存文件实例
2014/05/08 Javascript
详解JavaScript中的客户端消息框架设计原理
2015/06/24 Javascript
jQuery实现鼠标经过弹出提示信息的地图热点效果
2015/08/07 Javascript
jquery siblings获取同辈元素用法实例分析
2016/07/25 Javascript
EasyUi 打开对话框后控件赋值及赋值后不显示的问题解决办法
2017/01/19 Javascript
jQuery Ajax全解析
2017/02/13 Javascript
详解Angularjs 如何自定义Img的ng-load 事件
2017/02/15 Javascript
js实现横向拖拽导航条功能
2017/02/17 Javascript
JS实现直接运行html代码的方法
2017/03/13 Javascript
js实现彩色条纹滚动条效果
2017/03/15 Javascript
jQuery ajax请求struts action实现异步刷新
2017/04/19 jQuery
Vue 进阶教程之v-model详解
2017/05/06 Javascript
详解基于Vue+Koa的pm2配置
2017/10/24 Javascript
jQuery实现仿京东防抖动菜单效果示例
2018/07/06 jQuery
详解Angular Karma测试的持续集成实践
2019/11/15 Javascript
解决vue路由name同名,路由重复的问题
2020/08/05 Javascript
[06:20]2015国际邀请赛第三日top10
2015/08/08 DOTA
[52:10]LGD vs Optic Supermajor小组赛D组胜者组决赛 BO3 第二场 6.3
2018/06/04 DOTA
Python ORM框架SQLAlchemy学习笔记之数据查询实例
2014/06/10 Python
Python使用email模块对邮件进行编码和解码的实例教程
2016/07/01 Python
python中从str中提取元素到list以及将list转换为str的方法
2018/06/26 Python
对Python的zip函数妙用,旋转矩阵详解
2018/12/13 Python
pyqt5 tablewidget 利用线程动态刷新数据的方法
2019/06/17 Python
python 6.7 编写printTable()函数表格打印(完整代码)
2020/03/25 Python
CSS3结构性伪类选择器九种写法
2012/04/18 HTML / CSS
html5 touch事件实现触屏页面上下滑动(一)
2016/03/10 HTML / CSS
财务管理专业自荐信范文
2013/12/24 职场文书
校园十大歌手策划书
2014/02/01 职场文书
会计岗位描述
2014/02/22 职场文书
校园安全演讲稿
2014/05/09 职场文书
2014年预备党员群众路线教育实践活动对照检查材料思想汇报
2014/10/02 职场文书
学习雷锋精神倡议书
2015/04/27 职场文书
海底两万里读书笔记
2015/06/26 职场文书
pytorch 中nn.Dropout的使用说明
2021/05/20 Python