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的子进程(child_process)调用系统命令的方法分享
Jun 05 NodeJs
nodejs 整合kindEditor实现图片上传
Feb 03 NodeJs
nodejs实现遍历文件夹并统计文件大小
May 28 NodeJs
Highcharts+NodeJS搭建数据可视化平台示例
Jan 01 NodeJs
搭建简单的nodejs http服务器详解
Mar 09 NodeJs
nodejs模块nodemailer基本使用-邮件发送示例(支持附件)
Mar 28 NodeJs
nodejs结合Socket.IO实现的即时通讯功能详解
Jan 12 NodeJs
NodeJS服务器实现gzip压缩的示例代码
Oct 12 NodeJs
Nodejs监听日志文件的变化的过程解析
Aug 04 NodeJs
NodeJS多种创建WebSocket监听的方式(三种)
Jun 04 NodeJs
Nodejs环境实现socket通信过程解析
Jul 03 NodeJs
Node.js实现爬取网站图片的示例代码
Apr 04 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
mysql+php分页类(已测)
2008/03/31 PHP
php UTF-8、Unicode和BOM问题
2010/05/18 PHP
PHP 基于Yii框架中使用smarty模板的方法详解
2013/06/13 PHP
PHP+Mysql实现多关键字与多字段生成SQL语句的函数
2014/11/05 PHP
Yii学习总结之安装配置
2015/02/22 PHP
thinkphp框架page类与bootstrap分页(美化)
2017/06/25 PHP
PHP-FPM和Nginx的通信机制详解
2019/02/01 PHP
javascript OFFICE控件测试代码
2009/12/08 Javascript
javascript与CSS复习(二)
2010/06/29 Javascript
原生Js页面滚动延迟加载图片实现原理及过程
2013/06/24 Javascript
JavaScript控制各种浏览器全屏模式的方法、属性和事件介绍
2014/04/03 Javascript
Javascript中使用A标签获取当前目录的绝对路径方法
2015/03/02 Javascript
JS实现密码框根据焦点的获取与失去控制文字的消失与显示效果
2015/11/26 Javascript
JS实现快速的导航下拉菜单动画效果附源码下载
2016/11/01 Javascript
Vue-Cli中自定义过滤器的实现代码
2017/08/12 Javascript
jQuery实现IE输入框完成placeholder标签功能的方法
2017/09/20 jQuery
加载 vue 远程代码的组件实例详解
2017/11/20 Javascript
JS+HTML5 Canvas实现简单的写字板功能示例
2018/08/30 Javascript
jQuery内容过滤选择器与子元素过滤选择器用法实例分析
2019/02/20 jQuery
tensorflow建立一个简单的神经网络的方法
2018/02/10 Python
python3.6使用pickle序列化class的方法
2018/10/22 Python
python设置环境变量的作用和实例
2019/07/09 Python
python打印n位数“水仙花数”(实例代码)
2019/12/25 Python
python实现百度OCR图片识别过程解析
2020/01/17 Python
python 计算概率密度、累计分布、逆函数的例子
2020/02/25 Python
Python Tornado核心及相关原理详解
2020/06/24 Python
python 利用matplotlib在3D空间绘制二次抛物面的案例
2021/02/06 Python
美国标志性加大尺码时装品牌:Ashley Stewart
2016/12/15 全球购物
世界顶级户外运动品牌折扣网站:LeftLane Sports
2019/06/12 全球购物
房地产财务部员工岗位职责
2014/03/12 职场文书
《三个小伙伴》教学反思
2014/04/11 职场文书
党员创先争优活动总结
2014/05/04 职场文书
大学班级文化建设方案
2014/05/06 职场文书
学校评语大全
2014/05/06 职场文书
研究生导师推荐信
2014/09/06 职场文书
故意伤害辩护词
2015/05/21 职场文书