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实现的一个简单聊天室功能分享
Dec 06 NodeJs
nodejs中简单实现Javascript Promise机制的实例
Dec 06 NodeJs
详解Nodejs基于mongoose模块的增删改查的操作
Dec 21 NodeJs
nodejs+websocket实时聊天系统改进版
May 18 NodeJs
mac下的nodejs环境安装的步骤
May 24 NodeJs
nodejs模块学习之connect解析
Jul 05 NodeJs
详解nodejs的express如何自动生成项目框架
Jul 12 NodeJs
nodejs 图片预览和上传的示例代码
Sep 30 NodeJs
nodejs实现超简单生成二维码的方法
Mar 17 NodeJs
nodejs的路径问题的解决
Jun 30 NodeJs
详解nodejs 开发企业微信第三方应用入门教程
Mar 12 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 数据结构 算法描述 冒泡排序 bubble sort
2011/07/10 PHP
PHP验证码函数代码(简单实用)
2013/09/29 PHP
PHP使用ODBC连接数据库的方法
2015/07/18 PHP
php实现文件上传基本验证
2020/03/04 PHP
JS效率个人经验谈(8-15更新),加入range技巧
2007/01/09 Javascript
JQuery 网站换肤功能实现代码
2009/11/02 Javascript
jquery+json实现的搜索加分页效果
2010/03/31 Javascript
使用UglifyJS合并/压缩JavaScript的方法
2012/03/07 Javascript
JavaScript cookie的设置获取删除详解
2014/02/11 Javascript
javascript检测两个数组是否相似
2015/05/19 Javascript
Vue组件tree实现树形菜单
2017/04/13 Javascript
Promise.all中对于reject的处理方法
2018/08/01 Javascript
vue打包使用Nginx代理解决跨域问题
2018/08/27 Javascript
详解为生产环境编译Angular2应用的方法
2018/12/10 Javascript
vue 详情跳转至列表页实现列表页缓存
2019/03/27 Javascript
webgl实现物体描边效果的方法介绍
2019/11/27 Javascript
jQuery 判断元素是否存在然后按需加载内容的实现代码
2020/01/16 jQuery
在vscode 中设置 vue模板内容的方法
2020/09/02 Javascript
[00:08]DOTA2勇士令状等级奖励“天外飞星”
2019/05/24 DOTA
Python实现计算文件夹下.h和.cpp文件的总行数
2015/04/23 Python
在Python中使用判断语句和循环的教程
2015/04/25 Python
详解使用pymysql在python中对mysql的增删改查操作(综合)
2017/01/18 Python
pytorch-RNN进行回归曲线预测方式
2020/01/14 Python
Python threading.local代码实例及原理解析
2020/03/16 Python
详解CSS3阴影 box-shadow的使用和技巧总结
2016/12/03 HTML / CSS
施华洛世奇澳大利亚官网:SWAROVSKI澳大利亚
2017/01/06 全球购物
Casadei卡萨蒂官网:意大利奢侈鞋履品牌
2017/10/28 全球购物
暑期实习鉴定
2013/12/16 职场文书
临床医师专业个人自我评价
2014/01/08 职场文书
写给保洁员表扬信
2014/01/08 职场文书
高中家长寄语
2014/04/02 职场文书
国际金融专业自荐信
2014/07/05 职场文书
民主评议党员自我评议范文2014
2014/09/26 职场文书
2015年大学学生会工作总结
2015/05/13 职场文书
物资采购管理制度
2015/08/06 职场文书
2016年学校“3.12”植树节活动总结
2016/03/16 职场文书