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获取本机内网和外网ip地址的实现代码
Jun 01 NodeJs
nodejs npm包管理的配置方法及常用命令介绍
Jun 05 NodeJs
NodeJS和BootStrap分页效果的实现代码
Nov 07 NodeJs
Nodejs下DNS缓存问题浅析
Nov 16 NodeJs
进阶之初探nodeJS
Jan 24 NodeJs
Ajax异步文件上传与NodeJS express服务端处理
Apr 01 NodeJs
Nodejs之TCP服务端与客户端聊天程序详解
Jul 07 NodeJs
Nodejs 和Session 原理及实战技巧小结
Aug 25 NodeJs
nodejs判断文件、文件夹是否存在及删除的方法
Nov 10 NodeJs
nodejs简单实现TCP服务器端和客户端的聊天功能示例
Jan 04 NodeJs
NodeJS如何实现同步的方法示例
Aug 24 NodeJs
nodejs 递归拷贝、读取目录下所有文件和目录
Jul 18 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实现使用优酷土豆视频地址获取swf播放器分享地址
2014/06/05 PHP
[原创]ThinkPHP让../Public在模板不解析(直接输出)的方法
2015/10/09 PHP
Ajax中的JSON格式与php传输过程全面解析
2017/11/14 PHP
jquery 查找iframe父级页面元素的实现代码
2011/08/28 Javascript
JQuery一种取同级值的方式(比如你在GridView中)
2012/03/15 Javascript
基于jquery的禁用右键、文本选择功能、复制按键的实现代码
2013/08/27 Javascript
浅析Cookie中的Path与domain
2013/12/18 Javascript
jquery实现表格本地排序的方法
2015/03/11 Javascript
简介JavaScript中的setTime()方法的使用
2015/06/11 Javascript
jQuery简单实现仿京东商城的左侧菜单效果代码
2015/09/09 Javascript
js实现的二分查找算法实例
2016/01/21 Javascript
jQuery插件ajaxfileupload.js实现上传文件
2020/10/23 Javascript
jQuery中弹出iframe内嵌页面元素到父页面并全屏化的实例代码
2016/12/27 Javascript
浅谈mint-ui loadmore组件注意的问题
2017/11/08 Javascript
解决在vue项目中,发版之后,背景图片报错,路径不对的问题
2018/03/06 Javascript
浅谈JavaScript面向对象--继承
2019/03/20 Javascript
node 标准输入流和输出流代码实例
2019/09/19 Javascript
JavaScript实现多文件下载方法解析
2020/08/07 Javascript
python使用正则表达式提取网页URL的方法
2015/05/26 Python
利用Python如何生成随机密码
2016/04/20 Python
新手常见6种的python报错及解决方法
2018/03/09 Python
python交易记录整合交易类详解
2019/07/03 Python
Python绘制堆叠柱状图的实例
2019/07/09 Python
Python如何在单元测试中给对象打补丁
2020/08/03 Python
css3 矩阵的使用详解
2018/03/20 HTML / CSS
Fossil加拿大官网:化石手表、手袋、首饰及配饰
2019/04/23 全球购物
美国亚马逊旗下男装网站:East Dane(支持中文)
2019/09/25 全球购物
世界上最大的铁人三项商店:Tri UK
2020/11/04 全球购物
将"引用"作为函数参数有哪些特点
2013/04/05 面试题
行政人员岗位职责
2013/12/08 职场文书
兼职业务员岗位职责
2014/01/01 职场文书
投标邀请书范文
2014/01/31 职场文书
《美丽的小路》教学反思
2014/02/26 职场文书
学校办公室主任岗位职责
2015/04/01 职场文书
特种设备安全管理制度
2015/08/06 职场文书
使用ORM新增数据在Mysql中的操作步骤
2021/07/26 MySQL