使用nodejs下载风景壁纸


Posted in NodeJs onFebruary 05, 2017

需要用到的第三方模块有:

superagent

superagent-charset  (手动指定编码,解决GBK中文乱码)

cheerio

express

async (并发控制)

完整的代码,可以在我的github中可以下载。主要的逻辑逻辑在 netbian.js 中。

以彼岸桌面(http://www.netbian.com/)栏目下的风景壁纸(http://www.netbian.com/fengjing/index.htm)为例进行讲解。

1. 分析URL

使用nodejs下载风景壁纸

不难发现:

首页: 栏目/index.htm

分页: 栏目/index_具体页码.htm

知道这个规律,就可以批量下载壁纸了。

2. 分析壁纸缩略图,找到对应壁纸的大图

使用chrome的开发者工具,可以发现,缩略图列表在 class="list"的div里,a标签的href属性的值就是单张壁纸所在的页面。

使用nodejs下载风景壁纸

部分代码:

request
 .get(url)
 .end(function(err, sres){
 var $ = cheerio.load(sres.text);
 var pic_url = []; // 中等图片链接数组
 $('.list ul', 0).find('li').each(function(index, ele){
 var ele = $(ele);
 var href = ele.find('a').eq(0).attr('href'); // 中等图片链接
 if(href != undefined){
 pic_url.push(url_model.resolve(domain, href));
 }
 });
});

3. 以“http://www.netbian.com/desk/17662.htm”继续分析

打开这个页面,发现此页面显示的壁纸,依旧不是最高的分辨率。

点击“下载壁纸”按钮里的链接,打开新的页面。

使用nodejs下载风景壁纸

4. 以“http://www.netbian.com/desk/17662-1920x1080.htm”继续分析

打开这个页面,我们最终要下载的壁纸,放在一个table里面。如下图,http://img.netbian.com/file/2017/0203/bb109369a1f2eb2e30e04a435f2be466.jpg

才是我们最终要下载的图片的URL(幕后BOSS终于现身了(@ ̄? ̄@))。

使用nodejs下载风景壁纸

下载图片的代码:

request
.get(wallpaper_down_url)
.end(function(err, img_res){
 if(img_res.status == 200){
 // 保存图片内容
 fs.writeFile(dir + '/' + wallpaper_down_title + path.extname(path.basename(wallpaper_down_url)), img_res.body, 'binary', function(err){
 if(err) console.log(err);
 });
 }
});

打开浏览器,访问  http://localhost:1314/fengjing

选择栏目和页面,点击“开始”按钮:

使用nodejs下载风景壁纸

并发请求服务器,下载图片。

使用nodejs下载风景壁纸

完成~

使用nodejs下载风景壁纸

图片的存放目录按照 栏目+页码 的形式保存。

使用nodejs下载风景壁纸

附上完整的图片下载的代码:

/**
 * 下载图片
 * @param {[type]} url [图片URL]
 * @param {[type]} dir [存储目录]
 * @param {[type]} res [description]
 * @return {[type]} [description]
 */
var down_pic = function(url, dir, res){
 var domain = 'http://www.netbian.com'; // 域名
 request
 .get(url)
 .end(function(err, sres){
 var $ = cheerio.load(sres.text);
 var pic_url = []; // 中等图片链接数组
 $('.list ul', 0).find('li').each(function(index, ele){
 var ele = $(ele);
 var href = ele.find('a').eq(0).attr('href'); // 中等图片链接
 if(href != undefined){
 pic_url.push(url_model.resolve(domain, href));
 }
 });
 var count = 0; // 并发计数器
 var wallpaper = []; // 壁纸数组
 var fetchPic = function(_pic_url, callback){
 count++; // 并发加1
 var delay = parseInt((Math.random() * 10000000) % 2000);
 console.log('现在的并发数是:' + count + ', 正在抓取的图片的URL是:' + _pic_url + ' 时间是:' + delay + '毫秒');
 setTimeout(function(){
 // 获取大图链接
 request
 .get(_pic_url)
 .end(function(err, ares){
  var $$ = cheerio.load(ares.text);
  var pic_down = url_model.resolve(domain, $$('.pic-down').find('a').attr('href')); // 大图链接
  count--; // 并发减1
  // 请求大图链接
  request
  .get(pic_down)
  .charset('gbk') // 设置编码, 网页以GBK的方式获取
  .end(function(err, pic_res){
  var $$$ = cheerio.load(pic_res.text);
  var wallpaper_down_url = $$$('#endimg').find('img').attr('src'); // URL
  var wallpaper_down_title = $$$('#endimg').find('img').attr('alt'); // title
  // 下载大图
  request
  .get(wallpaper_down_url)
  .end(function(err, img_res){
  if(img_res.status == 200){
  // 保存图片内容
  fs.writeFile(dir + '/' + wallpaper_down_title + path.extname(path.basename(wallpaper_down_url)), img_res.body, 'binary', function(err){
   if(err) console.log(err);
  });
  }
  });
  wallpaper.push(wallpaper_down_title + '下载完毕<br />');
  });
  callback(null, wallpaper); // 返回数据
 });
 }, delay);
 };
 // 并发为2,下载壁纸
 async.mapLimit(pic_url, 2, function(_pic_url, callback){
 fetchPic(_pic_url, callback);
 }, function (err, result){
 console.log('success');
 res.send(result[0]); // 取下标为0的元素
 });
 });
};

特别需要注意的两点:

1. “彼岸桌面”网页的编码是“GBK”的。而nodejs本身只支持“UTF-8”编码。这里我们引入“superagent-charset”模块,用于处理“GBK”的编码。

使用nodejs下载风景壁纸

附上github里的一个例子

https://github.com/magicdawn/superagent-charset

使用nodejs下载风景壁纸

2.  nodejs是异步的,同一时间发送大量的请求,有可能被服务器认为是恶意请求而拒绝。 因此这里引入“async”模块,用于并发的处理,使用的方法是:mapLimit。

mapLimit(arr, limit, iterator, callback)

这个方法有4个参数:

第1个参数是数组。

第2个参数是并发请求的数量。

第3个参数是迭代器,通常是一个函数。

第4个参数是并发执行后的回调。

这个方法的作用是将arr中的每个元素同时并发limit次拿给iterator去执行,执行结果传给最后的callback。

后话

至此,便完成了图片的下载。

完整的代码,已经放在github上

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持三水点靠木!

NodeJs 相关文章推荐
nodejs教程之制作一个简单的文章发布系统
Nov 21 NodeJs
NodeJs基本语法和类型
Feb 13 NodeJs
浅谈Nodejs观察者模式
Oct 13 NodeJs
Nodejs的express使用教程
Nov 23 NodeJs
nodejs如何获取时间戳与时间差
Aug 03 NodeJs
docker中编译nodejs并使用nginx启动
Jun 23 NodeJs
理解nodejs的stream和pipe机制的原理和实现
Aug 12 NodeJs
nodejs连接mysql数据库及基本知识点详解
Mar 20 NodeJs
Nodejs中怎么实现函数的串行执行
Mar 02 NodeJs
Nodejs技巧之Exceljs表格操作用法示例
Nov 06 NodeJs
nodejs实现的http、https 请求封装操作示例
Feb 06 NodeJs
Nodejs 微信小程序消息推送的实现
Jan 20 NodeJs
nodeJs链接Mysql做增删改查的简单操作
Feb 04 #NodeJs
nodejs基础应用
Feb 03 #NodeJs
nodejs基础知识
Feb 03 #NodeJs
windows 下安装nodejs 环境变量设置
Feb 02 #NodeJs
图片上传之FileAPI与NodeJs
Jan 24 #NodeJs
初探nodeJS
Jan 24 #NodeJs
进阶之初探nodeJS
Jan 24 #NodeJs
You might like
php框架Phpbean说明
2008/01/10 PHP
特详细的PHPMYADMIN简明安装教程
2008/08/01 PHP
PHPExcel读取Excel文件的实现代码
2011/12/06 PHP
PHP中两个float(浮点数)比较实例分析
2015/09/27 PHP
Yii框架的布局文件实例分析
2019/09/04 PHP
jquery显示隐藏input对象
2014/07/21 Javascript
JavaScript动态修改背景颜色的方法
2015/04/16 Javascript
javascript电商网站抢购倒计时效果实现
2015/11/19 Javascript
jQuery实现表格文本框淡入更改值后淡出效果
2016/09/27 Javascript
BootStrap Fileinput插件和Bootstrap table表格插件相结合实现文件上传、预览、提交的导入Excel数据操作步骤
2017/08/07 Javascript
浅谈Koa服务限流方法实践
2017/10/23 Javascript
jquery ztree实现右键收藏功能
2017/11/20 jQuery
微信小程序页面生命周期详解
2018/01/31 Javascript
微信小程序实现导航栏选项卡效果
2020/06/19 Javascript
swiper.js插件实现pc端文本上下滑动功能示例
2018/12/03 Javascript
JavaScript继承的特性与实践应用深入详解
2018/12/30 Javascript
[41:17]VG vs Optic 2018国际邀请赛小组赛BO2 第二场 8.19
2018/08/21 DOTA
Python Web框架Flask中使用新浪SAE云存储实例
2015/02/08 Python
解决python3在anaconda下安装caffe失败的问题
2017/06/15 Python
Python生成器generator用法示例
2018/08/10 Python
使用50行Python代码从零开始实现一个AI平衡小游戏
2018/11/21 Python
Python解析多帧dicom数据详解
2020/01/13 Python
基于Python数据结构之递归与回溯搜索
2020/02/26 Python
django 模版关闭转义方式
2020/05/14 Python
使用anaconda安装pytorch的实现步骤
2020/09/03 Python
Python tkinter之Bind(绑定事件)的使用示例
2021/02/05 Python
香港迪士尼乐园酒店预订:Hong Kong Disneyland Hotels
2017/05/02 全球购物
Wojas罗马尼亚网站:波兰皮鞋品牌
2018/11/01 全球购物
软件售后服务方案
2014/05/29 职场文书
贯彻落实“八项规定”思想汇报
2014/09/13 职场文书
先进班组事迹材料
2014/12/25 职场文书
2015年中秋节演讲稿
2015/03/20 职场文书
家庭经济困难证明
2015/06/23 职场文书
MongoDB 常用的crud操作语句
2021/06/20 MongoDB
Matplotlib绘制条形图的方法你知道吗
2022/03/21 Python
Win10本地连接不见了怎么恢复? win10系统电脑本地连接不见了解决方法
2023/01/09 数码科技