//======================================================
// https://www.meitulu.com图片批量下载Node.js爬虫1.03
// 1.00 完成图片爬虫,手动输入页数和目录
// 1.01 改写。
// 1.02 手动输入页面url,然后自动解析
// 1.03 从命令行获得页面url,然后自动解析
// 2017年11月6日
//======================================================

// 内置https模块,提供了https服务器和客户端功能
var https=require("https");

// 内置http模块,提供了http服务器和客户端功能
var http=require("http");

var zlib = require('zlib'); 

// cheerio模块,提供了类似jQuery的功能
var cheerio = require("cheerio");

// 内置文件处理模块
var fs=require('fs');

// 请求参数JSON
var options;

// request请求
var req;

//--------------------------------------
// 程序入口
//--------------------------------------
function getInput(){
    console.log("请输入页面URL:");
    process.stdin.resume();
    process.stdin.setEncoding('utf8');
    process.stdin.on('data',function(text){
        // trim()是必须的!
        start(text.trim());
    });
}

//--------------------------------------
// 开始下载
//--------------------------------------
function start(pageUrl){
    console.log("页面URL="+pageUrl);

    var hostName="";
    var Path="";
    var arr=pageUrl.split("/");
    hostName=arr[2];
    Path="/"+arr[3]+"/"+arr[4];

    // 初始化options
    options={
        hostname:hostName,
            port:443,
            path:Path,// 子路径
          method:'GET',
           agent:false,
            gzip: true,
    };

    req=https.request(options,function(resp){
        var html = [];

        resp.on("data", function(data) {
            html.push(data);
        })
        resp.on("end", function() {
            var buffer = Buffer.concat(html);

            zlib.gunzip(buffer, function(err, decoded) {
                //console.log(decoded.toString());// gzip解压后的html文本
                var body=decoded.toString();
                var $ = cheerio.load(body);
                var endIndex=0;
                var folder="";

                // 查找所有class为c_l的节点下面的p节点
                $(".c_l p").each(function(index,element){
                    if(index==2){
                        var text=$(element).text();

                        var arr=text.split(" ");
                        endIndex=arr[1];
                    }
                })   

                // 查找所有class为c_l的节点下面的p节点
                $(".content center img").each(function(index,element){
                    if(index==0){
                        var text=$(element).attr("src");

                        var arr=text.split("/");
                        folder=arr[arr.length-2];
                    }
                }) 

                console.log(endIndex);
                console.log(folder);    

                fs.mkdir('./'+folder,function(err){
                    if(err){
                        console.log("目录"+folder+"已经存在");
                    }
                });

                // 下载图片
                for(var i=1;i<=endIndex;i++){
                    downloadPic(folder,i);
                }

            })
        }).on("error", function() {
            console.log("获取失败")
        })
    });

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

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

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

//--------------------------------------
// 下载图片
// folder:图片所在url的目录
// pinctureIndex:图片序号
//--------------------------------------
function downloadPic(folder,pinctureIndex){
    console.log("开始下载"+pinctureIndex);

    // 初始化options
    options={
        hostname:'mtl.ttsqgs.com',// 这里别加http://,否则会出现ENOTFOUND错误
            port:80,
            path:'/images/img/'+folder+'/'+pinctureIndex+'.jpg',// 子路径
          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+"/"+pinctureIndex+".jpg";
            fs.writeFile(fileName, imgData, "binary", function(err){
                if(err){
                    console.log("文件"+fileName+"下载失败.");
                }
                console.log(fileName+"下载成功");
            });
        });
    });

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

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

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

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

2017年11月6日16:43:18

Node.js meitulu图片批量下载爬虫1.03版的更多相关文章

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

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

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

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

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

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

  4. Node.js meitulu图片批量下载爬虫1.02版

    以前版本需要先查看网页源码,然后肉眼找到图片数量和子目录,虽说不费事,但多少有点不方便. 于是修改了一下,用cheerio自己去找找到图片数量和子目录,只要修改页面地址就行了.至此社会又前进了一步. ...

  5. Node.js meitulu图片批量下载爬虫1.01版

    在 http://www.cnblogs.com/xiandedanteng/p/7614051.html 一文我曾经书写过一个图片下载爬虫,但原有程序不是为下载图片而设计故有些绕,于是稍微改写了一下 ...

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

    原有1.05版程序没有断点续传模式,现在在最近程序基础上改写一版1.051. //====================================================== // m ...

  7. Node.js mm131图片批量下载爬虫1.01 增加断点续传功能

    这里的断点续传不是文件下载时的断点续传,而是指在爬行页面时有时会遇到各种网络中断而从中断前的页面及其数据继续爬行的过程,这个过程和断点续传原理上相似故以此命名.我的具体做法是:在下载出现故障或是图片已 ...

  8. Node.js abaike图片批量下载爬虫1.02

    //====================================================== // abaike图片批量下载爬虫1.02 // 用最近的断点续传框架改写原有1.01 ...

  9. Node.js nvshens图片批量下载爬虫1.01

    //====================================================== // nvshens图片批量下载爬虫1.01 // 用最近的断点续传框架改写原有1.0 ...

随机推荐

  1. c++文件流写入到execl中

    #include <iostream> #include <fstream> #include <string> using namespace std; int ...

  2. WPF中添加一个文本输入框,按Enter回车,执行绑定的Command

    在WPF+WMMV模式中使用键盘和鼠标事件的绑定代码如下: <TextBox x:Name="SearchBox" Text="{Binding SearchTex ...

  3. pythn抓取网页小例子

    import urllib.request import re from tkinter import * win = Tk() win.geometry('500x300+400+300') t = ...

  4. lua返回服务器信息

    ngx.header.content_type = "text/plain"; ngx.say(tostring(ngx.var.request_uri));ngx.say(tos ...

  5. yii2.0在model里自定义数据表

    无需多言,直接撸代码 class Zhuanjia extends \yii\db\ActiveRecord { public static function tableName() { return ...

  6. (2)三剑客之grep

    1)grep和egrep定义grep:在文件中全局查找指定的正则表达式,并打印所有包含该表达式的行egrep:扩展的egrep,支持更多的正则表达式元字符2)命令格式语法:grep [选项] patt ...

  7. (三)mysql数据库基本操作

    (1)SQL语句:结构化查询语句 DDL语句 数据定义语言:数据库丶表丶视图丶索引丶存储过程丶函数丶create drop alter DML语句 数据库操作语言:插入数据insert,删除数据del ...

  8. MySql 分页关键字(limit)

    mysql分页关键字: limit m,n --m:表示从哪一行开始查,n:查询多少条 oracle分页关键字:: rownum SqlServer:top(2005以下版本)  row_number ...

  9. python socket 连续send,出现粘包问题

    使用网上socket代码实现ssh功能,如下: server.py #服务端Linux系统下:处理命令并返回import socketimport os#声明类型,生成socket链接对象server ...

  10. QT_QMAKE_EXECUTABLE reported QT_INSTALL_LIBS as /usr/lib/i386-linux-gnu but ...

    $sudo apt-get install libqt4-dev done!!!