nodejs制作爬虫实现批量下载图片


Posted in NodeJs onMay 19, 2017

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

nodejs制作爬虫实现批量下载图片

1. 爬取图片链接

因为之前也写过nodejs爬虫功能(参见: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关心的最后产生的值。

提供了两种方式:

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

顺序执行。 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学习笔记之Connect中间件模块(二)
Jan 27 NodeJs
使用DNode实现php和nodejs之间通信的简单实例
Jul 06 NodeJs
使用Angular和Nodejs、socket.io搭建聊天室及多人聊天室
Aug 21 NodeJs
nodejs和php实现图片访问实时处理
Jan 05 NodeJs
使用nodejs下载风景壁纸
Feb 05 NodeJs
nodejs中模块定义实例详解
Mar 18 NodeJs
nodejs开发微信小程序实现密码加密
Jul 11 NodeJs
NodeJs项目中关闭ESLint的方法
Aug 09 NodeJs
通过Nodejs搭建网站简单实现注册登录流程
Jun 14 NodeJs
NodeJS开发人员常见五个错误理解
Oct 14 NodeJs
分享node.js实现简单登录注册的具体代码
Apr 26 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
NodeJS、NPM安装配置步骤(windows版本) 以及环境变量详解
May 13 #NodeJs
You might like
收音机术语解释
2021/03/01 无线电
PHP+Mysql日期时间如何转换(UNIX时间戳和格式化日期)
2012/07/15 PHP
解析centos中Apache、php、mysql 默认安装路径
2013/06/25 PHP
php项目中百度 UEditor 简单安装调试和调用
2015/07/15 PHP
ThinkPHP数据操作方法总结
2015/09/28 PHP
非常实用的php验证码类
2016/05/15 PHP
PHP获取客户端及服务器端IP的封装类
2016/07/21 PHP
jquery1.4.2 for Visual studio 2010 模板文件
2010/07/14 Javascript
TextArea设置MaxLength属性最大输入值的js代码
2012/12/21 Javascript
使用jQuery实现返回顶部
2015/01/26 Javascript
jQuery实现鼠标划过展示大图的方法
2015/03/09 Javascript
nodejs爬虫抓取数据乱码问题总结
2015/07/03 NodeJs
JavaScript生成SQL查询表单的方法
2015/08/13 Javascript
解决js函数闭包内存泄露问题的办法
2016/01/25 Javascript
JavaScript操作select元素和option的实例代码
2016/01/29 Javascript
js拖拽的原型声明和用法总结
2016/04/04 Javascript
基于JS实现移动端向左滑动出现删除按钮功能
2017/02/22 Javascript
jQuery 利用ztree实现树形表格的实例代码
2017/09/27 jQuery
React Native时间转换格式工具类分享
2017/10/24 Javascript
JavaScript登录验证基础教程
2017/11/01 Javascript
jQuery+Cookie实现切换皮肤功能【附源码下载】
2018/03/25 jQuery
angular4 共享服务在多个组件中数据通信的示例
2018/03/30 Javascript
vue项目实现表单登录页保存账号和密码到cookie功能
2018/08/31 Javascript
pymongo实现多结果进行多列排序的方法
2015/05/16 Python
python中urllib.unquote乱码的原因与解决方法
2017/04/24 Python
Python爬虫小技巧之伪造随机的User-Agent
2018/09/13 Python
Python3爬虫教程之利用Python实现发送天气预报邮件
2018/12/16 Python
python买卖股票的最佳时机(基于贪心/蛮力算法)
2019/07/05 Python
python-序列解包(对可迭代元素的快速取值方法)
2019/08/24 Python
python利用paramiko实现交换机巡检的示例
2020/09/22 Python
老生常谈CSS中的长度单位
2016/06/27 HTML / CSS
CSS3实现多样的边框效果
2018/05/04 HTML / CSS
先进党支部事迹材料
2014/01/13 职场文书
高校教师自荐信范文
2014/03/13 职场文书
学习张林森心得体会
2014/09/10 职场文书
雨花台导游词
2015/02/06 职场文书