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观察者模式
Oct 13 NodeJs
nodejs服务搭建教程 nodejs访问本地站点文件
Apr 07 NodeJs
浅析 NodeJs 的几种文件路径
Jun 07 NodeJs
Nodejs回调加超时限制两种实现方法
Jun 09 NodeJs
详解nodejs的express如何自动生成项目框架
Jul 12 NodeJs
nodejs多版本管理总结
Apr 03 NodeJs
NodeJS模块与ES6模块系统语法及注意点详解
Jan 04 NodeJs
使用nodejs分离html文件里的js和css详解
Apr 12 NodeJs
nodejs检测因特网是否断开的解决方案
Apr 17 NodeJs
nodejs搭建本地服务器并访问文件操作示例
May 11 NodeJs
详解NodeJs项目 CentOs linux服务器线上部署
Sep 16 NodeJs
nodejs对mongodb数据库的增加修删该查实例代码
Jan 05 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打包压缩文件之ZipArchive方法用法分析
2016/04/30 PHP
PHP生成指定范围内的N个不重复的随机数
2019/03/18 PHP
PHP连续签到功能实现方法详解
2019/12/04 PHP
公共js在页面底部加载的注意事项介绍
2013/07/18 Javascript
简单时间提示DEMO从0开始一直进行计时
2013/11/19 Javascript
JavaScript设置body高度为浏览器高度的方法
2015/02/09 Javascript
JavaScript中创建字典对象(dictionary)实例
2015/03/31 Javascript
JS实现模拟风力的雪花飘落效果
2015/05/13 Javascript
创建你的第一个AngularJS应用的方法
2015/06/16 Javascript
jquery特效 点击展示与隐藏全文
2015/12/09 Javascript
原生JS实现匀速图片轮播动画
2016/10/18 Javascript
微信小程序技巧之show内容展示,上传文件编码问题
2017/01/23 Javascript
使用vue.js编写蓝色拼图小游戏
2017/03/17 Javascript
Node.js  事件循环详解及实例
2017/08/06 Javascript
微信小程序实现根据字母选择城市功能
2017/08/16 Javascript
浅析Vue.js 中的条件渲染指令
2018/11/19 Javascript
举例讲解Python中的死锁、可重入锁和互斥锁
2015/11/05 Python
使用Python下载歌词并嵌入歌曲文件中的实现代码
2015/11/13 Python
Python实现图片滑动式验证识别方法
2017/11/09 Python
MAC中PyCharm设置python3解释器
2017/12/15 Python
Python爬取成语接龙类网站
2018/10/19 Python
在双python下设置python3为默认的方法
2018/10/31 Python
python 矢量数据转栅格数据代码实例
2019/09/30 Python
通过 Django Pagination 实现简单分页功能
2019/11/11 Python
keras处理欠拟合和过拟合的实例讲解
2020/05/25 Python
python 实现波浪滤镜特效
2020/12/02 Python
详解python日志输出使用配置文件格式
2021/02/10 Python
挪威户外活动服装和装备购物网站:Bergfreunde挪威
2016/10/20 全球购物
Clarks鞋法国官方网站:英国其乐鞋品牌
2018/02/11 全球购物
三查三看党性分析材料
2014/02/18 职场文书
2014年大学团支部工作总结
2014/12/02 职场文书
2014年乡镇团委工作总结
2014/12/18 职场文书
志愿者服务宣传标语口号
2015/12/26 职场文书
三严三实学习心得体会(精选N篇)
2016/01/05 职场文书
javascript的var与let,const之间的区别详解
2022/02/18 Javascript
Win11筛选键导致键盘失灵怎么解决? Win11关闭筛选键的技巧
2022/04/08 数码科技