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服务器(1):一个简单nodejs服务器例子
Dec 18 NodeJs
NodeJS学习笔记之(Url,QueryString,Path)模块
Jan 13 NodeJs
NodeJS Web应用监听sock文件实例
Feb 18 NodeJs
nodejs实现获取某宝商品分类
May 28 NodeJs
浅析nodejs实现Websocket的数据接收与发送
Nov 19 NodeJs
详解NodeJs支付宝移动支付签名及验签
Jan 06 NodeJs
Ajax异步文件上传与NodeJS express服务端处理
Apr 01 NodeJs
mac下的nodejs环境安装的步骤
May 24 NodeJs
在Debian(Raspberry Pi)树莓派上安装NodeJS的教程详解
Sep 19 NodeJs
nodejs异步编程基础之回调函数用法分析
Dec 26 NodeJs
用Electron写个带界面的nodejs爬虫的实现方法
Jan 29 NodeJs
Nodejs 微信小程序消息推送的实现
Jan 20 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的面试题集,附我的答案和分析(一)
2006/11/19 PHP
并发下常见的加锁及锁的PHP具体实现代码
2010/10/12 PHP
php生成缩略图示例代码分享(使用gd库实现)
2014/01/20 PHP
Ajax中的JSON格式与php传输过程全面解析
2017/11/14 PHP
PHP对称加密算法(DES/AES)类的实现代码
2017/11/14 PHP
Yii框架实现对数据库的CURD操作示例
2019/09/03 PHP
JavaScript DOM 学习第七章 表单的扩展
2010/02/19 Javascript
javascript判断iphone/android手机横竖屏模式的函数
2011/12/20 Javascript
jQuery操作CheckBox的方法介绍(选中,取消,取值)
2014/02/04 Javascript
JS实现窗口加载时模拟鼠标移动的方法
2015/06/03 Javascript
Jquery全屏相册插件zoomvisualizer具有调节放大与缩小功能
2015/11/02 Javascript
javascript:void(0)点击登录没反应怎么解决
2015/11/13 Javascript
JavaScript实现下拉菜单的显示和隐藏
2016/01/05 Javascript
JS模拟bootstrap下拉菜单效果实例
2016/06/17 Javascript
w3c编程挑战_初级脚本算法实战篇
2017/06/23 Javascript
详解如何解决vue开发请求数据跨域的问题(基于浏览器的配置解决)
2018/11/12 Javascript
浅谈Vue.js之初始化el以及数据的绑定说明
2019/11/14 Javascript
Python入门篇之字典
2014/10/17 Python
python集合类型用法分析
2015/04/08 Python
Python字典实现简单的三级菜单(实例讲解)
2017/07/31 Python
Python引用计数操作示例
2018/08/23 Python
Python3 串口接收与发送16进制数据包的实例
2019/06/12 Python
Python实现简单的列表冒泡排序和反转列表操作示例
2019/07/10 Python
整个世界的设计师家具在哈恩:Designathome
2019/03/25 全球购物
如何用JQuery进行表单验证
2013/05/29 面试题
大学生求职自荐信
2013/12/12 职场文书
房地产销售计划书
2014/01/10 职场文书
迟到检讨书900字
2014/01/14 职场文书
销售顾问工作计划书
2014/09/15 职场文书
质检员岗位职责
2015/02/03 职场文书
人事行政助理岗位职责
2015/04/11 职场文书
如何书写邀请函?
2019/06/24 职场文书
2019事业单位个人工作总结范文
2019/08/26 职场文书
angular异步验证器防抖实例详解
2022/03/31 Javascript
我们认为中短波广播场强仪的最佳组合
2022/04/05 无线电
Java Lambda表达式常用的函数式接口
2022/04/07 Java/Android