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教程之异步I/O
Nov 21 NodeJs
浅谈NodeJS中require路径问题
May 07 NodeJs
nodejs学习笔记之路由
Mar 27 NodeJs
NodeJs测试框架Mocha的安装与使用
Mar 28 NodeJs
nodejs中解决异步嵌套循环和循环嵌套异步的问题
Jul 12 NodeJs
nodejs读取并去重excel文件
Apr 22 NodeJs
nodeJS服务器的创建和重新启动的实现方法
May 12 NodeJs
nodejs文件夹深层复制功能
Sep 03 NodeJs
纯异步nodejs文件夹(目录)复制功能
Sep 03 NodeJs
nodejs中使用archive压缩文件的实现代码
Nov 26 NodeJs
Nodejs实现WebSocket代码实例
May 19 NodeJs
NodeJS模块Buffer原理及使用方法解析
Nov 11 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+Mysql+jQuery实现动态展示信息
2011/10/08 PHP
PHP的可变变量名的使用方法分享
2012/02/05 PHP
PHP使用zlib扩展实现GZIP压缩输出的方法详解
2018/04/09 PHP
javascript cookie解码函数(兼容ff)
2008/03/17 Javascript
js的写法基础分析
2011/01/17 Javascript
JavaScript操作XML 使用百度RSS作为新闻源示例
2012/02/17 Javascript
Textbox控件注册回车事件及触发按钮提交事件具体实现
2013/03/04 Javascript
一个简单的全屏图片上下打开显示网页效果示例
2014/07/08 Javascript
jQuery实现列表自动滚动循环滚动展示新闻
2014/08/22 Javascript
为何JS操作的href都是javascript:void(0);呢
2015/11/12 Javascript
Web程序员必备的7个JavaScript函数
2016/06/14 Javascript
详解JS-- 浮点数运算处理
2016/11/28 Javascript
web 屏蔽BackSpace键实例代码
2016/12/24 Javascript
微信小程序之MaterialDesign--input组件详解
2017/02/15 Javascript
easyUI下拉列表点击事件使用方法
2017/05/18 Javascript
angularjs实现table表格td单元格单击变输入框/可编辑状态示例
2019/02/21 Javascript
基于Layui自定义模块的使用方法详解
2019/09/14 Javascript
基于JS实现计算24点算法代码实例解析
2020/07/23 Javascript
Python 'takes exactly 1 argument (2 given)' Python error
2016/12/13 Python
简单谈谈Python中的几种常见的数据类型
2017/02/10 Python
Python实现针对中文排序的方法
2017/05/09 Python
python中MethodType方法介绍与使用示例
2017/08/03 Python
python输出100以内的质数与合数实例代码
2018/07/08 Python
华为2019校招笔试题之处理字符串(python版)
2019/06/25 Python
从多个tfrecord文件中无限读取文件的例子
2020/02/17 Python
家得宝加拿大家装网上商店:The Home Depot加拿大
2016/08/27 全球购物
洛佩桑酒店官方网站:Lopesan Hotels
2019/04/15 全球购物
零件设计自荐信范文
2013/11/27 职场文书
工作失误检讨书范文大全
2014/01/13 职场文书
教师研修随笔感言
2014/01/23 职场文书
棉花姑娘教学反思
2014/02/15 职场文书
学校欢迎标语
2014/06/18 职场文书
文明倡议书
2015/01/19 职场文书
小学班主任自我评价
2015/03/11 职场文书
Spring Security使用单点登录的权限功能
2022/04/03 Java/Android
Python docx库删除复制paragraph及行高设置图片插入示例
2022/07/23 Python