这个爬虫在abaike爬虫的基础上改改图片路径和下一页路径就出来了,代码如下:

//======================================================
// umei图片批量下载Node.js爬虫1.00
// 2017年11月13日
//======================================================

// 内置http模块
var http=require("http");

// 内置文件处理模块,用于创建目录和图片文件
var fs=require('fs');

// cheerio模块,提供了类似jQuery的功能,用于从HTML code中查找图片地址和下一页
var cheerio = require("cheerio");

// 请求参数JSON。http和https都有使用
var options;

// request请求
var req;

// 图片数组,找到的图片地址会放到这里
var pictures=[];

//--------------------------------------
// 爬取网页,找图片地址,再爬
// pageUrl sample:http://www.umei.cc/meinvtupian/waiguomeinv/12667.htm
// pageUrl sample:http://www.umei.cc/meinvtupian/waiguomeinv/12667_3.htm
//--------------------------------------
function crawl(pageUrl){
    console.log("Current page="+pageUrl);

    // 得到hostname和path
    var currUrl=pageUrl.replace("http://","");
    var pos=currUrl.indexOf("/");
    var hostname=currUrl.slice(0,pos);
    var path=currUrl.slice(pos);
    //console.log("hostname="+hostname);
    //console.log("path="+path);

    // 初始化options
    options={
        hostname:hostname,
            port:80,
            path:path,// 子路径
          method:'GET',
    };

    req=http.request(options,function(resp){
        resp.setEncoding('utf8');
        var body="";

        resp.on('data',function(chunk){
            body+=chunk;
        });

        resp.on('end',function(){
            //console.log("body="+body);
            var $ = cheerio.load(body);
            var picCount=0;

            // 找图片放入数组
            $(".ImageBody p img").each(function(index,element){
                var picUrl=$(element).attr("src");
                //console.log(picUrl);

                if(picUrl.indexOf('.jpg')!=-1){
                    pictures.push(picUrl);
                    picCount++;
                }
            })
            console.log("找到图片"+picCount+"张.");

            var nextPageUrl=null;
            // 找下一页
            $(".NewPages ul li a").each(function(index,element){
                var text=$(element).text();

                if(text.indexOf('下一页')!=-1){
                    nextPageUrl=$(element).attr("href");
                    nextPageUrl="http://www.umei.cc/"+nextPageUrl;// 把省略部分加上
                    console.log("找到下一页.");
                }
            })

            if(nextPageUrl==null){
                console.log(pageUrl+"已经是最后一页了.");
                download(pictures);
            }else{
                //console.log("下一页是"+nextPageUrl);
                crawl(nextPageUrl);
            }
        });
    });

    // 超时处理
    req.setTimeout(10000,function(){
        req.abort();
    });

    // 出错处理
    req.on('error',function(err){
        if(err.code=="ECONNRESET"){
            console.log('[crawl]socket端口连接超时。');
            console.log(err);
        }else{
            console.log('请求发生错误,err.code:'+err.code);
            console.log(err);
        }
    });

    // 请求结束
    req.end();
}

var total=0;
var succeed=0;
var failed=0;

//--------------------------------------
// 下载图片
//--------------------------------------
function download(pictures){
    var folder='pictures('+getNowFormatDate()+")";
    // 创建目录
    fs.mkdir('./'+folder,function(err){
        if(err){
            console.log("目录"+folder+"已经存在");
        }
    });

    total=pictures.length;
    console.log("总计有"+total+"张图片将被下载.");
    appendToLogfile(folder,"总计有"+total+"张图片将被下载.\n");
    for(var i=0;i<pictures.length;i++){
        var picUrl=pictures[i];
        downloadPic(picUrl,folder);
    }
}

//--------------------------------------
// 写log文件
//--------------------------------------
function appendToLogfile(folder,text){
    fs.appendFile('./'+folder+'/log.txt', text, function (err) {
        if(err){
            console.log("不能书写log文件");
            console.log(err);
        }
    });
}

//--------------------------------------
// 取得当前时间
//--------------------------------------
function getNowFormatDate() {
    var date = new Date();
    var seperator1 = "-";
    var seperator2 = "_";
    var month = date.getMonth() + 1;
    var strDate = date.getDate();
    if (month >= 1 && month <= 9) {
        month = "0" + month;
    }
    if (strDate >= 0 && strDate <= 9) {
        strDate = "0" + strDate;
    }
    var currentdate =date.getFullYear() + seperator1 + month + seperator1 + strDate
            + " " + date.getHours() + seperator2 + date.getMinutes()
            + seperator2 + date.getSeconds();
    return currentdate;
}

//--------------------------------------
// 下载单张图片
// picUrl sample:http://www.avbaike.net/wp-content/uploads/2016/08/108.jpg
//--------------------------------------
function downloadPic(picUrl,folder){
    console.log("图片:"+picUrl+"下载开始");

    // 得到hostname和path
    var currUrl=picUrl.replace("http://","");
    var pos=currUrl.indexOf("/");
    var hostname=currUrl.slice(0,pos);
    var path=currUrl.slice(pos);
    //console.log("hostname="+hostname);
    //console.log("path="+path);

    var picName=currUrl.slice(currUrl.lastIndexOf("/"));

    // 初始化options
    options={
        hostname:hostname,
            port:80,
            path:path,// 子路径
          method:'GET',
    };

    req=http.request(options,function(resp){
        var imgData = "";
        resp.setEncoding("binary"); 

        resp.on('data',function(chunk){
            imgData+=chunk;
        });

        resp.on('end',function(){        

            // 创建文件
            var fileName="./"+folder+picName;
            fs.writeFile(fileName, imgData, "binary", function(err){
                if(err){
                    console.log("[downloadPic]文件"+fileName+"下载失败.");
                    console.log(err);
                    appendToLogfile(folder,"文件"+fileName+"下载失败.\n");
                    failed++;
                }else{
                    console.log("文件"+fileName+"下载成功");
                    succeed++;
                }
            });
        });
    });

    // 超时处理
    req.setTimeout(7500,function(){
        req.abort();
    });

    // 出错处理
    req.on('error',function(err){
        if(err){
            console.log('[downloadPic]文件'+picUrl+"下载失败,"+'因为'+err);
            appendToLogfile(folder,"文件"+picUrl+"下载失败.\n");
        }

        failed++;
    });

    // 请求结束
    req.end();
}

//--------------------------------------
// 程序入口
//--------------------------------------
function getInput(){

    process.stdout.write("\033[35m 请输入第一页URL:\033[039m");    //紫色
    process.stdin.resume();
    process.stdin.setEncoding('utf8');    

    process.stdin.on('data',function(text){
        process.stdin.end();// 退出输入状态
        crawl(text.trim());// trim()是必须的!
    });
}

// 调用getInput函数,程序开始
getInput();

2017年11月13日20:05:44

Node.js umei图片批量下载Node.js爬虫1.00的更多相关文章

  1. Node.js aitaotu图片批量下载Node.js爬虫1.00版

    即使是https网页,解析的方式也不是一致的,需要多试试. 代码: //====================================================== // aitaot ...

  2. Node.js abaike图片批量下载Node.js爬虫1.01版

    //====================================================== // abaike图片批量下载Node.js爬虫1.01 // 1.01 修正了输出目 ...

  3. Node.js abaike图片批量下载Node.js爬虫1.00版

    这个与前作的差别在于地址的不规律性,需要找到下一页的地址再爬过去找. //====================================================== // abaik ...

  4. Node.js mimimn图片批量下载爬虫 1.00

    这个爬虫在Referer设置上和其它爬虫相比有特殊性.代码: //====================================================== // mimimn图片批 ...

  5. Node.js nvshens图片批量下载爬虫 1.00

    //====================================================== // www.nvshens.com图片批量下载Node.js爬虫1.00 // 此程 ...

  6. Node.js meitulu图片批量下载爬虫1.06版

    //====================================================== // https://www.meitulu.com图片批量下载Node.js爬虫1. ...

  7. Node.js meitulu图片批量下载爬虫 1.05版(Final最终版)

    //====================================================== // https://www.meitulu.com图片批量下载Node.js爬虫1. ...

  8. Node.js meitulu图片批量下载爬虫1.04版

    //====================================================== // https://www.meitulu.com图片批量下载Node.js爬虫1. ...

  9. Node.js meitulu图片批量下载爬虫1.03版

    //====================================================== // https://www.meitulu.com图片批量下载Node.js爬虫1. ...

随机推荐

  1. CentOS7.5删除旧的内核

    [root@localhost ~]# uname -r3.10.0-862.3.2.el7.x86_64 [root@localhost ~]# rpm -qa | grep kernelkerne ...

  2. python 自定义过滤器

    文件目录结构: 新建文件并且命名为“templatetags” , 然后复制 __init__.py文件,拷贝到templatetags文件夹里, __pycache__文件夹可以忽略哈,那是程序运行 ...

  3. No module named '_Sqlite3' 解决方法

    今晚,在学习Python的时候,(学习链接:http://yidao620c.github.io/blog/20150420/simpleblog-01.html(搭载自己的博客案例)): 想为系统生 ...

  4. ZSTU OJ 4272 最佳淘汰算法

    线段树. 处理出每个位置下一个位置是哪里.然后搞个线段树找一下最大值就可以了. #include<map> #include<set> #include<ctime> ...

  5. Flask实战第39天:完成前台注册界面

    在template下创建目录front,该目录用于存放前台页面的所有模板 在front下创建登录模板 <!DOCTYPE html> <html lang="en" ...

  6. angularjs学习笔记1-angular总体简介及其特点

    以前开发(web或者移动端)前端主要使用jQuery+原生js,如果使用某些前端UI框架的话,它自己还可能提供一些API可以使用.而且目前很多UI框架都是基于jQuery的,所以说一下由jQuery跨 ...

  7. CodeForces - 992D Nastya and a Game

    题面在这里! 显然一段区间的 mul - sum * k = 0 才合法,然鹅我们发现sum * k 对于本题的数据来说最大才是1e18,也就是说mul必须得<=1e18. 我们不妨从这里入手, ...

  8. Luogu P3362 Cool loves shaxian 生成函数

    题意: 定义f(i)=∑ k∣i k^d(i≤n),给出q个询问,每个询问询问区间[l,r]的f(i)的和. n<=1e7 d<=1e18 q<=5e4 可以发现f(i)是个积性函数 ...

  9. BZOJ 1827 [Usaco2010 Mar]gather 奶牛大集会(树形DP)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1827 [题目大意] 给出一棵有点权和边权的树, 请确定一个点,使得每个点到这个点的距离 ...

  10. python基础之封装与绑定方法

    封装 1.什么是封装: 封:属性对外隐藏,但对内开放 装:申请一个名称空间,往里装入一系列名字/属性 2.为什么要封装: 封装数据属性:不让外部使用者直接使用数据,需要类内部开辟一个接口,让外部通过接 ...