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服务器(5):事件处理程序
Dec 18 NodeJs
Nodejs学习笔记之Stream模块
Jan 13 NodeJs
nodejs URL模块操作URL相关方法介绍
Mar 03 NodeJs
NodeJs的优势和适合开发的程序
Aug 14 NodeJs
详解Nodejs基于mongoose模块的增删改查的操作
Dec 21 NodeJs
解析NodeJS异步I/O的实现
Apr 13 NodeJs
使用vs code开发Nodejs程序的使用方法
Sep 21 NodeJs
详解NODEJS的http实现
Jan 04 NodeJs
NodeJs项目中关闭ESLint的方法
Aug 09 NodeJs
NodeJs实现简易WEB上传下载服务器
Aug 10 NodeJs
nodejs开发一个最简单的web服务器实例讲解
Jan 02 NodeJs
浅谈Node的内存泄露问题
May 06 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
php adodb连接不同数据库
2009/03/19 PHP
php单例模式的简单实现方法
2016/06/10 PHP
PHP进制转换实例分析(2,8,16,36,64进制至10进制相互转换)
2017/02/04 PHP
yii2 resetful 授权验证详解
2017/05/18 PHP
表单的一些基本用法与技巧
2006/07/15 Javascript
关于 文本框默认值 的操作js代码
2012/01/12 Javascript
jQuery中 noConflict() 方法使用
2013/04/25 Javascript
一个仿糯米弹框效果demo
2014/07/22 Javascript
举例详解Python中smtplib模块处理电子邮件的使用
2015/06/24 Javascript
Bootstrap入门书籍之(一)排版
2016/02/17 Javascript
JavaScript函数绑定用法实例分析
2017/11/14 Javascript
echarts学习笔记之箱线图的分析与绘制详解
2017/11/22 Javascript
JavaScript实现单例模式实例分享
2017/12/22 Javascript
解决vue 格式化银行卡(信用卡)每4位一个符号隔断的问题
2018/09/14 Javascript
webpack的pitching loader详解
2019/09/23 Javascript
axios封装与传参示例详解
2020/10/18 Javascript
[01:38]完美世界DOTA2联赛PWL S3 集锦第四期
2020/12/21 DOTA
Python简单实现子网掩码转换的方法
2016/04/13 Python
解决Matplotlib图表不能在Pycharm中显示的问题
2018/05/24 Python
python3爬虫之设计签名小程序
2018/06/19 Python
Python OpenCV处理图像之图像像素点操作
2018/07/10 Python
python3.6.3转化为win-exe文件发布的方法
2018/10/31 Python
Python求均值,方差,标准差的实例
2019/06/29 Python
opencv3/python 鼠标响应操作详解
2019/12/11 Python
Python爬虫库BeautifulSoup的介绍与简单使用实例
2020/01/25 Python
Python3和PyCharm安装与环境配置【图文教程】
2020/02/14 Python
django实现更改数据库某个字段以及字段段内数据
2020/03/31 Python
Python网页解析器使用实例详解
2020/05/30 Python
css3实现背景颜色渐变让图片不再是唯一的实现方式
2012/12/18 HTML / CSS
详解如何解决H5开发使用wx.hideMenuItems无效果不生效
2021/01/20 HTML / CSS
应聘自荐信
2013/12/14 职场文书
幼儿教师演讲稿
2014/05/06 职场文书
建筑院校毕业生求职信
2014/06/13 职场文书
2014年工程部工作总结
2014/11/25 职场文书
2016学校先进党组织事迹材料
2016/02/29 职场文书
python-opencv 中值滤波{cv2.medianBlur(src, ksize)}的用法
2021/06/05 Python