Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

node自定义模块:一个壁纸下载小工具 #4

Open
phenomLi opened this issue Sep 21, 2017 · 0 comments
Open

node自定义模块:一个壁纸下载小工具 #4

phenomLi opened this issue Sep 21, 2017 · 0 comments

Comments

@phenomLi
Copy link
Owner

phenomLi commented Sep 21, 2017

作为微软忠实用户,Windowsphone,win8,win10一路走来,一直都很喜欢里面的一样东西,就是bing提供的锁屏壁纸,都很唯美。网络上已经有很多很成熟的bing壁纸下载工具了,但是这次我决定自己做一个,以node模块形式的,虽然很简陋,但是这不重要,贵在学到东西。


首先确保电脑已经安装node和npm环境

第一步:编写主代码

首先先要把获取bing壁纸的api找出来,我在网上找到一个

http://cn.bing.com/HPImageArchive.aspx?format=js&idx=0&n=1
访问后浏览器返回了如下信息:
{
	"images":
	[{
		"startdate":"20170920",
		"fullstartdate":"201709201600",
		"enddate":"20170921",
		"url":"/az/hprichbg/rb/CorricellaMarina_ZH-CN11169480773_1920x1080.jpg",
		"urlbase":"/az/hprichbg/rb/CorricellaMarina_ZH-CN11169480773",
		"copyright":"普罗奇达岛,意大利那不勒斯湾 (© Frank Chmura/age fotostock)",
		"copyrightlink":"http://www.bing.com/search?q=%E6%99%AE%E7%BD%97%E5%A5%87%E8%BE%BE%E5%B2%9B&form=hpcapt&mkt=zh-cn",
		"quiz":"/search?q=Bing+homepage+quiz&filters=WQOskey:%22HPQuiz_20170920_CorricellaMarina%22&FORM=HPQUIZ",
		"wp":true,
		"hsh":"d2bbe5539a47b4d03a5bc541d09a9ecf",
		"drk":1,
		"top":1,
		"bot":1,
		"hs":[]
	}],
	"tooltips":{
		"loading":"正在加载...",
		"previous":"上一个图像",
		"next":"下一个图像",
		"walle":"此图片不能下载用作壁纸。",
		"walls":"下载今日美图。仅限用作桌面壁纸。"
	}
}

里面响应的是一个json格式的数据,我们先要把里面有用的东西提取出来。比如里面的url,还有copyright,用作保存的图片的名字。那么现在我们可以开始写代码了:

const http = require('http'),  //引入http模块用作请求信息
      fs = require('fs');       //引入fs模块用作读写文件

首先我们引入需要用到的模块,一个是http模块一个是fs模块,然后我们就可以请求内容了:

http.get('http://cn.bing.com/HPImageArchive.aspx?format=js&idx=0&n=1', res => {

});

使用http的get方法可以请求一个url,在回调函数里面的res(response)可以监听到响应的数据,但是由于http协议的限制,数据只能一分一分传过来。用res监听data事件可以获取需要的数据,当所有数据传送完毕则会响应end事件,于是我们可以这样写:

http.get('http://cn.bing.com/HPImageArchive.aspx?format=js&idx=0&n=1', res => {

    let chunk = '',
        data = '',
        url = '',
        copyright = '';

    //res响应data事件,不断接收数据
    res.on('data', data => {
        chunk += data;
    });

    //res接收数据完毕,提取需要的信息
    res.on('end', data => {

        //接收到的json为String,先解析为Object
        data = JSON.parse(chunk);
    });

});

获取到响应的json数据,那我们就可以提取其中我们需要的内容了,这部分很简单:

http.get('http://cn.bing.com/HPImageArchive.aspx?format=js&idx=0&n=1', res => {

    let chunk = '',
        data = '',
        url = '',
        copyright = '';

    //res响应data事件,不断接收数据
    res.on('data', data => {
        chunk += data;
    });

    //res接收数据完毕,提取需要的信息
    res.on('end', data => {

        //接收到的json为String,先解析为Object
        data = JSON.parse(chunk);

        //提取内容
        url = data.images[0].url;
        copyright = data.images[0].copyright;

    });
});

我们把url和copyright都打印出来看看是什么样子:

很好,现在需要的信息都拿到了。但是我们现在拿到的只是一个url,我们要的是把url里面的图片文件下载下来,很显然我们要再进行一次http请求。为了避免进入callback hell,我再另外定义一个downloader函数,具体思路和上面大同小异:

const downloader = (url, copyright, callback) => {
    //当我尝试直接访问url的时候却显示找不到文件,一番折腾之后,发现原来要在url前面加上bing的主机名
    http.get('http://s.cn.bing.net' + url, res => {

        let pic = '';

        //设置数据格式为二进制
        res.setEncoding('binary');

        //res响应data事件,不断接收数据
        res.on('data', data => {
            pic += data;
        });

        //res接收数据完毕,提取需要的信息
        res.on('end', () => {

            //写入磁盘
            fs.writeFile('./bing/' + copyright + '.jpg', pic, 'binary', err => {
                if(!err){

                    //执行回调
                    callback();
                }
            });
        });
    });
};

需要注意的是,要先把数据格式设为二进制格式,不然没法识别。
最后在主方法那里调用downloader函数:

downloader(url, copyright, () => {
      console.log('图片保存成功.');
});

现在看起来程序应该是没问题了,跑起来试试:

可以看到bing文件夹下面也成功新增了图片:

到此,主程序完成。


第二步:包装为node模块

这部分十分简单,我们可以用`module.exports`将函数或对象包装成commonjs模块,所以我们在主程序作以下修改:
module.exports = function() {
  //主程序。。。
};

这样就可以了。我们新建一个文件,尝试引入并调用这个我们自己定义的模块:

const wallpaperDownloader = require('./new');    //引入模块

wallpaperDownloader();

运行看看效果:

很明显是没有问题的。

第三步:将模块分享到npm

写好了模块之后,我们可以用npm工具把模块分享到npm官网。 首先要在npm官网注册好账号,然后在命令行使用
$ npm login

登录账号,之后再用

$ npm init

为你的模块设置一些基本信息,最后用

$ npm publish

发布你的模块,以上步骤都很简单,就不展开说明了。
发布以后,可以登录npm官网: https://www.npmjs.com/ 查看一下你的包是否有成功发布。
现在搜索我刚刚发布的包的名字:

可以看到包已经成功发布了,版本为1.0.0

@phenomLi phenomLi changed the title 搞一个属于自己的node模块:一个壁纸下载小工具 node自定义模块:一个壁纸下载小工具 Sep 21, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant