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 实现模拟form表单上传文件
Jul 14 NodeJs
nodejs中实现路由功能
Dec 29 NodeJs
NodeJs基本语法和类型
Feb 13 NodeJs
NodeJS实现阿里大鱼短信通知发送
Jan 17 NodeJs
使用nodejs中httpProxy代理时候出现404异常的解决方法
Aug 15 NodeJs
nodejs中使用HTTP分块响应和定时器示例代码
Mar 19 NodeJs
详解nodejs异步I/O和事件循环
Jun 07 NodeJs
深入学习nodejs中的async模块的使用方法
Jul 12 NodeJs
nodejs Assert中equal(),strictEqual(),deepEqual(),strictDeepEqual()比较
Sep 18 NodeJs
nodejs实现简单的gulp打包
Dec 21 NodeJs
Nodejs实现图片上传、压缩预览、定时删除功能
Oct 25 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 网上商城促销设计实例代码
2012/02/17 PHP
PHP内核探索:变量概述
2014/01/30 PHP
yii上传文件或图片实例
2014/04/01 PHP
在WordPress中获取数据库字段内容和添加主题设置菜单
2016/01/11 PHP
PHP+MySQL实现模糊查询员工信息功能示例
2018/06/01 PHP
php微信公众号开发之答题连闯三关
2018/10/20 PHP
jquery api参考 visualjquery 中国线路 速度快
2007/11/30 Javascript
ie focus bug 解决方法
2009/09/03 Javascript
javascript Firefox与IE 替换节点的方法
2010/02/24 Javascript
下拉菜单点击实现连接跳转功能的js代码
2013/05/19 Javascript
JS 获取滚动条高度示例代码
2013/10/24 Javascript
JavaScript类属性的访问方式详解
2014/02/11 Javascript
jQuery实现自动滚动到页面顶端的方法
2015/05/22 Javascript
如何用javascript计算文本框还能输入多少个字符
2015/07/29 Javascript
AngularJS基础 ng-keypress 指令简单示例
2016/08/02 Javascript
微信小程序实现留言板
2018/10/31 Javascript
详解在微信小程序的JS脚本中使用Promise来优化函数处理
2019/03/06 Javascript
vue实现按需加载组件及异步组件功能
2019/05/27 Javascript
nodejs实现获取本地文件夹下图片信息功能示例
2019/06/22 NodeJs
微信小程序实现滚动Tab选项卡
2020/11/16 Javascript
[01:13:46]iG vs Winstrike 2018国际邀请赛小组赛BO2 第一场 8.16
2018/08/17 DOTA
对于Python编程中一些重用与缩减的建议
2015/04/14 Python
python处理图片之PIL模块简单使用方法
2015/05/11 Python
在Python的Flask框架中验证注册用户的Email的方法
2015/09/02 Python
解决使用export_graphviz可视化树报错的问题
2019/08/09 Python
基于Python爬取搜狐证券股票过程解析
2020/11/18 Python
pandas将list数据拆分成行或列的实现
2020/12/13 Python
Mytheresa英国官网:拥有160多个奢侈品品牌
2016/10/09 全球购物
微软台湾官方网站:Microsoft台湾
2018/08/15 全球购物
Seavenger官网:潜水服、浮潜、靴子和袜子
2020/03/05 全球购物
美国购物网站:Clickhere2shop
2021/01/28 全球购物
若通过ObjectOutputStream向一个文件中多次以追加方式写入object,为什么用ObjectInputStream读取这些object时会产生StreamCorruptedException?
2016/10/17 面试题
大学活动策划书范文
2014/01/10 职场文书
公司周年庆典邀请函
2014/01/12 职场文书
群众路线领导对照材料
2014/08/23 职场文书
Python Pandas数据分析之iloc和loc的用法详解
2021/11/11 Python