福利 - 不过百行代码的爬虫爬取美女图

极乐网
极乐网 发布于 2017-01-05 16:38:08 浏览:692 类型:转载 - 教程 分类:Node.js - 前端 二维码: 转载说明
序言

闲的无聊,看到一个段子网站的美女福利还不错,迫于福利加载太慢看的不过瘾,就想用Nodejs写个简单爬虫全部爬下来看多好..... 此处省略5000字.....

准备

要爬,首先得要有目标,我呢,就把目标锁定到了 某哈,然后呢就是用浏览器来分析分析其中的规律

福利 - 不过百行代码的爬虫爬取美女图

从中可以看到每一条段子都是一个 .joke-list-item, 当点击下一页的时候 url中地址的最后一位数就表示分页的页码。有些图片是缩略图,我们把缩略图和正常图的地址进行了比较,发现他们的地址格式是一样的,缩略图在small文件夹下,大图在big文件夹下。分析完了我们就可以写代码了。

开始

这个简单爬虫分两个部分,1、获取图片地址。2、进行下载。因为下载是一个耗时的操作,所以两个部分分开了,这样也有利于后期改动。导入必要的模块,使用cheerio 是第三方模块,可以使用 npm install cheerio 进行安装

var http = require('http');			// http 网路
var cheerio = require('cheerio');	// html 解析
var fs = require("fs");				// 流

var queryHref = "http://www.haha.mx/topic/1/new/"; 	// 设置被查询的目标网址
var querySearch = 1;								// 设置分页位置

var urls = [];			// 所有待下载的图片地址


这个是解析图片地址方法

/**
 * 根据url和参数获取分页内容
 * @param {String}: url
 * @param {int}: serach
 */
function getHtml(href, serach) {
  var pageData = "";
  var req = http.get(href + serach, function(res) {
    res.setEncoding('utf8');
    res.on('data', function(chunk) {
      pageData += chunk;
    });

    res.on('end', function() {
      $ = cheerio.load(pageData);
      var html = $(".joke-list-item .joke-main-content a img");

      for(var i = 0; i < html.length; i++) {
        var src = html[i].attribs.src;
        // 筛选部分广告,不是真的段子
        if (src.indexOf("http://image.haha.mx") > -1) {
          urls.push(html[i].attribs.src)
        }
      }

    });
  });
}


这个是下载图片的方法

/**
 * 下载图片
 * @param {String} imgurl:图片地址
 */
function downImg(imgurl) {
  var narr = imgurl.replace("http://image.haha.mx/", "").split("/")
  
  http.get(imgurl.replace("/small/", "/big/"), function(res) {
    var imgData = "";
    //一定要设置response的编码为binary否则会下载下来的图片打不开
    res.setEncoding("binary");   

    res.on("data", function(chunk) {
      imgData += chunk;
    });
    
    res.on("end", function() {
      var savePath = "./upload/topic1/" + narr[0]  + narr[1] + narr[2] + "_" + narr[4];
      // 保存图片
      fs.writeFile(savePath, imgData, "binary", function(err) {
        if(err) {
          console.log(err);
        }
      });
    });
  });
}


好,到这里核心的东西就写完了,然后就是组装一下,让他运行起来

附一个完整代码:

var http = require('http');      // http 网路
var cheerio = require('cheerio');  // html 解析
var fs = require("fs");        // 流

// 设置被查询的目标网址
var queryHref = "http://www.haha.mx/topic/1/new/";   
// 设置分页位置
var querySearch = 1;                

var urls = [];


/**
 * 根据url和参数获取分页内容
 * @param {String}: url
 * @param {int}: serach
 */
function getHtml(href, serach) {
  var pageData = "";
  var req = http.get(href + serach, function(res) {
    res.setEncoding('utf8');
    res.on('data', function(chunk) {
      pageData += chunk;
    });

    res.on('end', function() {
      $ = cheerio.load(pageData);
      var html = $(".joke-list-item .joke-main-content a img");

      for(var i = 0; i < html.length; i++) {
        var src = html[i].attribs.src;
        // 筛选部分广告,不是真的段子
        if (src.indexOf("http://image.haha.mx") > -1) {
          urls.push(html[i].attribs.src)
        }
      }
      if (serach == pagemax) {
        console.log("图片链接获取完毕!" + urls.length);
        console.log("链接总数量:" + urls.length);
        if (urls.length > 0) {
          downImg(urls.shift());
        } else {
          console.log("下载完毕");
        }
      }
    });
  });
}


/**
 * 下载图片
 * @param {String} imgurl:图片地址
 */
function downImg(imgurl) {
  var narr = imgurl.replace("http://image.haha.mx/", "").split("/")
  
  http.get(imgurl.replace("/small/", "/big/"), function(res) {
    var imgData = "";
    //一定要设置response的编码为binary否则会下载下来的图片打不开
    res.setEncoding("binary"); 

    res.on("data", function(chunk) {
      imgData += chunk;
    });
    
    res.on("end", function() {
      var savePath = "./upload/topic1/" + narr[0]  + narr[1] + narr[2] + "_" + narr[4];
      fs.writeFile(savePath, imgData, "binary", function(err) {
        if(err) {
          console.log(err);
        }  else {
          console.log(narr[0]  + narr[1] + narr[2] + "_" + narr[4]);
          if (urls.length > 0) {
            downImg(urls.shift());
          } else {
            console.log("下载完毕");
          }
        }
      });
    });
  });
}

var pagemax = 10;    // 获取10页的内容
function start(){
  console.log("开始获取图片连接");
  for (var i = 1 ; i <= pagemax ; i++) {
    getHtml(queryHref, i);
  }
}

start();


因为nodejs是异步的,所以在 start 方法中的for之后调用下载是不行,这个时候显示的 urls 中是没有数据的。所以就是在 getHtml 中 等所有的连接分析完毕之后在调用 downImg,downImg下载完成之后在进行下一个下载。项目目录很简单,如图:

福利 - 不过百行代码的爬虫爬取美女图

然后我们切换到项目目录,执行 node app , 然后就静静的等待把,每次下载完一个会有对应的文件名打印出来的。

福利 - 不过百行代码的爬虫爬取美女图

最后会出现 下载完毕!,之后就....... 你懂得......

这个是一个很简单的,当然后续你可以加上数据库,数据更新之类的.....

放几张我爬到的图



















注意前方高能


注意前方高能


注意前方高能

























福利 - 不过百行代码的爬虫爬取美女图

福利 - 不过百行代码的爬虫爬取美女图

福利 - 不过百行代码的爬虫爬取美女图

嘘... 不要告诉别人....
z
给个赞 3 人点赞
收藏 6 人收藏
评论 已有 4 条评论;以下用户言论只代表其个人观点,不代表 前端网(QDFuns) 的观点或立场。
登录 以后才能发表评论
最新评论
Lin_Grady
Lin_Grady昨天 16:564F
我之前也玩过,死活下载不到图片,后来发现爬虫不难,怎么突破网站的反爬虫才是关键...
有办法么?
举报 支持 (0) 回复 (0)
认真你就输了丶
认真你就输了丶2017-01-05 17:30:153F
需要搭什么环境吗 //@极乐网:这个。。。。你可以摸索摸索! //@认真你就输了丶:厉害了 Word哥  一直想学 有好的教学资源吗
举报 支持 (0) 回复 (0)
极乐网
极乐网2017-01-05 17:22:482F
这个。。。。你可以摸索摸索! //@认真你就输了丶:厉害了 Word哥  一直想学 有好的教学资源吗
举报 支持 (0) 回复 (1)
认真你就输了丶
认真你就输了丶2017-01-05 17:04:091F
厉害了 Word哥  一直想学 有好的教学资源吗
举报 支持 (0) 回复 (1)
极乐网 极乐网 作者

https://zhuanlan.zhihu.com/dreawer

作者最新