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写的一个简单项目打包工具
May 11 NodeJs
nodejs 实现模拟form表单上传文件
Jul 14 NodeJs
轻松创建nodejs服务器(3):代码模块化
Dec 18 NodeJs
Nodejs中解决cluster模块的多进程如何共享数据问题
Nov 10 NodeJs
nodejs实现邮件发送服务实例分享
Mar 29 NodeJs
详解如何在NodeJS项目中优雅的使用ES6
Apr 22 NodeJs
NodeJs模拟登陆正方教务
Apr 28 NodeJs
nodeJS实现简单网页爬虫功能的实例(分享)
Jun 08 NodeJs
原生nodejs使用websocket代码分享
Apr 07 NodeJs
对mac下nodejs 更新到最新版本的最新方法(推荐)
May 17 NodeJs
Nodejs使用archiver-zip-encrypted库加密压缩文件时报错(解决方案)
Nov 18 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
文章推荐系统(二)
2006/10/09 PHP
Laravel 框架基于自带的用户系统实现登录注册及错误处理功能分析
2020/04/14 PHP
Laravel 框架路由原理与路由访问实例分析
2020/04/14 PHP
javascript 一个函数对同一元素的多个事件响应
2009/07/25 Javascript
JavaScript 的方法重载效果
2009/08/07 Javascript
基于jquery.Jcrop的头像编辑器
2010/03/01 Javascript
js动态移动滚动条至底部示例代码
2014/04/24 Javascript
jQuery实现多按钮单击变色
2014/11/27 Javascript
对JavaScript客户端应用编程的一些建议
2015/06/24 Javascript
JavaScript 常见安全漏洞和自动化检测技术
2015/08/21 Javascript
详解Javascript ES6中的箭头函数(Arrow Functions)
2016/08/24 Javascript
easyui简介_动力节点Java学院整理
2017/07/14 Javascript
vue移动端路由切换实例分析
2018/05/14 Javascript
微信小程序基于picker实现级联菜单
2019/02/15 Javascript
vue-cli中使用高德地图的方法示例
2019/03/28 Javascript
Vue 中 a标签上href无法跳转的解决方式
2019/11/12 Javascript
Vue关于组件化开发知识点详解
2020/05/13 Javascript
Vue使用富文本编辑器Vue-Quill-Editor(含图片自定义上传服务、清除复制粘贴样式等)
2020/05/15 Javascript
深入理解python函数递归和生成器
2016/06/06 Python
Python实现在线音乐播放器
2017/03/03 Python
Python使用django框架实现多人在线匿名聊天的小程序
2017/11/29 Python
Python缓存技术实现过程详解
2019/09/25 Python
如何基于python操作json文件获取内容
2019/12/24 Python
深入了解如何基于Python读写Kafka
2019/12/31 Python
jupyter notebook 添加kernel permission denied的操作
2020/04/21 Python
Python如何定义接口和抽象类
2020/07/28 Python
canvas学习总结三之绘制路径-线段
2019/01/31 HTML / CSS
乐高积木玩具美国官网:LEGO Shop US
2016/09/16 全球购物
美国新兴城市生活方式零售商:VILLA
2017/12/06 全球购物
公共汽车、火车和飞机票的通用在线预订和销售平台:INFOBUS
2019/11/30 全球购物
如何理解委托
2012/01/06 面试题
工程质量承诺书
2014/03/27 职场文书
我的老师教学反思
2014/05/01 职场文书
优秀应届生求职信
2014/06/16 职场文书
领导班子党的群众路线教育实践活动对照检查材料
2014/09/25 职场文书
2015年会计工作总结范文
2015/05/26 职场文书