源码网商城,靠谱的源码在线交易网站 我的订单 购物车 帮助

源码网商城

使用nodejs下载风景壁纸

  • 时间:2022-10-12 14:18 编辑: 来源: 阅读:
  • 扫一扫,手机访问
摘要:使用nodejs下载风景壁纸
[b]需要用到的第三方模块有:[/b] [b]superagent[/b] [b]superagent-charset  (手动指定编码,解决GBK中文乱码)[/b] [b]cheerio[/b] [b]express[/b] [b]async (并发控制)[/b] 完整的代码,可以在[url=https://github.com/kakaxiaoshizi/spider]我的github[/url]中可以下载。主要的逻辑逻辑在 netbian.js 中。 以彼岸桌面([url=http://www.netbian.com/]http://www.netbian.com/[/url])栏目下的风景壁纸([url=http://www.netbian.com/fengjing/index.htm]http://www.netbian.com/fengjing/index.htm[/url])为例进行讲解。 [b]1. 分析URL [/b] [b][img]http://files.jb51.net/file_images/article/201702/2017020418072842.png[/img] [/b] 不难发现: 首页: 栏目/index.htm 分页: 栏目/index_具体页码.htm 知道这个规律,就可以批量下载壁纸了。 [b]2. 分析壁纸缩略图,找到对应壁纸的大图[/b] 使用chrome的开发者工具,可以发现,缩略图列表在 class="list"的div里,a标签的href属性的值就是单张壁纸所在的页面。 [img]http://files.jb51.net/file_images/article/201702/2017020418072843.png[/img] [b]部分代码:[/b]
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));
 }
 });
});
[b]3. 以“http://www.netbian.com/desk/17662.htm”继续分析[/b] 打开这个页面,发现此页面显示的壁纸,依旧不是最高的分辨率。 点击“下载壁纸”按钮里的链接,打开新的页面。 [img]http://files.jb51.net/file_images/article/201702/2017020418072844.png[/img] [b]4. 以“http://www.netbian.com/desk/17662-1920x1080.htm”继续分析[/b] 打开这个页面,我们最终要下载的壁纸,放在一个table里面。如下图,[url=http://img.netbian.com/file/2017/0203/bb109369a1f2eb2e30e04a435f2be466.jpg]http://img.netbian.com/file/2017/0203/bb109369a1f2eb2e30e04a435f2be466.jpg[/url] 才是我们最终要下载的图片的URL(幕后BOSS终于现身了(@ ̄ー ̄@))。 [img]http://files.jb51.net/file_images/article/201702/2017020418072845.png[/img] [b]下载图片的代码:[/b]
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);
 });
 }
});
打开浏览器,访问  [url=http://localhost:1314/fengjing]http://localhost:1314/fengjing[/url] 选择栏目和页面,点击“开始”按钮: [img]http://files.jb51.net/file_images/article/201702/2017020418072846.png[/img] 并发请求服务器,下载图片。 [img]http://files.jb51.net/file_images/article/201702/2017020418072847.png[/img] 完成~ [img]http://files.jb51.net/file_images/article/201702/2017020418072848.png[/img] 图片的存放目录按照 栏目+页码 的形式保存。 [img]http://files.jb51.net/file_images/article/201702/2017020418072849.png[/img] [b]附上完整的图片下载的代码:[/b]
/**
 * 下载图片
 * @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的元素
 });
 });
};
[b]特别需要注意的两点:[/b] [b]1. “彼岸桌面”网页的编码是“GBK”的。而nodejs本身只支持“UTF-8”编码。这里我们引入“superagent-charset”模块,用于处理“GBK”的编码。[/b] [b][img]http://files.jb51.net/file_images/article/201702/2017020418072850.png[/img] [/b] 附上github里的一个例子 [url=https://github.com/magicdawn/superagent-charset]https://github.com/magicdawn/superagent-charset[/url] [img]http://files.jb51.net/file_images/article/201702/2017020418072951.png[/img] [b]2.  nodejs是异步的,同一时间发送大量的请求,有可能被服务器认为是恶意请求而拒绝。 因此这里引入“async”模块,用于并发的处理,使用的方法是:mapLimit。[/b] [code]mapLimit(arr, limit, iterator, callback) [/code] [b]这个方法有4个参数:[/b] 第1个参数是数组。 第2个参数是并发请求的数量。 第3个参数是迭代器,通常是一个函数。 第4个参数是并发执行后的回调。 这个方法的作用是将arr中的每个元素同时并发limit次拿给iterator去执行,执行结果传给最后的callback。 [b]后话[/b] 至此,便完成了图片的下载。 完整的代码,已经放在[url=https://github.com/kakaxiaoshizi/spider]github上[/url] 以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持编程素材网!
  • 全部评论(0)
联系客服
客服电话:
400-000-3129
微信版

扫一扫进微信版
返回顶部