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入门详解(多篇文章结合)
Mar 07 NodeJs
nodejs中exports与module.exports的区别详细介绍
Jan 14 NodeJs
基于NodeJS的前后端分离的思考与实践(五)多终端适配
Sep 26 NodeJs
Nodejs全栈框架StrongLoop推荐
Nov 09 NodeJs
windows下安装nodejs及框架express
Aug 07 NodeJs
NodeJS使用formidable实现文件上传
Oct 27 NodeJs
NodeJs下的测试框架Mocha的简单介绍
Feb 22 NodeJs
nodejs个人博客开发第五步 分配数据
Apr 12 NodeJs
用Nodejs搭建服务器访问html、css、JS等静态资源文件
Apr 28 NodeJs
NodeJS 将文件夹按照存放路径变成一个对应的JSON的方法
Oct 17 NodeJs
详解利用nodejs对本地json文件进行增删改查
Sep 20 NodeJs
在nodejs中创建child process的方法
Jan 26 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
经典的PHPer为什么被认为是草根?
2007/04/02 PHP
php 静态变量的初始化
2009/11/15 PHP
PHP中全局变量global和$GLOBALS[]的区别分析
2012/08/06 PHP
php随机显示图片的简单示例
2014/02/15 PHP
PHP命令Command模式用法实例分析
2018/08/08 PHP
javascript基本类型详解
2014/11/28 Javascript
javascript修改图片src的方法
2015/01/27 Javascript
js随机生成字母数字组合的字符串 随机动画数字
2015/09/02 Javascript
JavaScript——DOM操作——Window.document对象详解
2016/07/14 Javascript
总结javascript中的六种迭代器
2016/08/16 Javascript
面试常见的js算法题
2017/03/23 Javascript
详解vue-cli开发环境跨域问题解决方案
2017/06/06 Javascript
django实现分页的方法
2015/05/26 Python
django开发之settings.py中变量的全局引用详解
2017/03/29 Python
pycharm在调试python时执行其他语句的方法
2018/11/29 Python
python 利用pandas将arff文件转csv文件的方法
2019/02/12 Python
python 图片去噪的方法示例
2019/07/09 Python
python实现DEM数据的阴影生成的方法
2019/07/23 Python
Python中Flask-RESTful编写API接口(小白入门)
2019/12/11 Python
浅析python 定时拆分备份 nginx 日志的方法
2020/04/27 Python
Django Admin后台模型列表页面如何添加自定义操作按钮
2020/11/11 Python
python 求两个向量的顺时针夹角操作
2021/03/04 Python
全天然狗零食:Best Bully Sticks
2016/09/22 全球购物
THE OUTNET美国官网:国际设计师品牌折扣网站
2017/03/07 全球购物
Superdry瑞典官网:英国日本街头风品牌
2017/05/17 全球购物
Ajax和javascript的区别
2013/07/20 面试题
校园广播稿500字
2014/02/04 职场文书
2014全国两会学习心得体会1000字
2014/03/10 职场文书
眼镜促销方案
2014/03/15 职场文书
毕业横幅标语
2014/10/08 职场文书
党支部先进事迹材料
2014/12/24 职场文书
高中社区服务活动报告
2015/02/05 职场文书
新员工试用期工作总结2015
2015/05/28 职场文书
微软Win11有哪些隐藏功能? windows11多个功能汇总
2021/11/21 数码科技
面试分析分布式架构Redis热点key大Value解决方案
2022/03/13 Redis
MySQL分区表管理命令汇总
2022/03/21 MySQL