在一些大型网站上的比较大的背景图片都是异步加载的,在bing上也验证了一下,在网速慢的情况下,背景显示的是黑色,之后才显示图片。所以我想,图片地址应该是从接口返回,之后异步加载的。
这里使用的是request模块,也是比较常用的取接口内容的模块。
const request = require('request'); const fs = require('fs'); const path = require('path'); request.get('http://cn.bing.com/HPImageArchive.aspx?format=js&idx=0&n=1&mkt=zh-CN', (error, response, body) => { const img = JSON.parse(body).images[0]; const arr = img.url.split('/'); const str = arr[arr.length - 1]; request(img.url).pipe(fs.createWriteStream(path.join('./img', str))); console.log(`${new Date()}${str} is ok!`); });
代码其实很简单
先将img的资源取出来,然后使用fs文件模块将img资源放到目录下的’img’文件夹内。
但是问题来了,这下代码只是用来保存当前一天的图片存到文件夹里,每天还是得敲一个node app.js才能获取图片,和之前的右键保存并没提升多少效率。
既然要每天跑一次,那么我们使用定时任务去做不就好了,这里又使用了一个新的模块叫node-schedule。
node-schedule是专门用来做定时任务的,详情可以去看官方文档,我这里就只简单的贴下代码。
const schedule = require('node-schedule'); const rule = new schedule.RecurrenceRule(); rule.dayOfWeek = [0, new schedule.Range(1, 6)]; rule.hour = 8; rule.minute = 0; schedule.scheduleJob(rule, () => { require('./src/get.js'); });
那么问题又来了,我总不能每天都开着电脑吧?解决方法其实很简单,放到服务器去执行不就行了。但是放在服务器我本地怎么用壁纸呢?这个更简单了,直接使用git,同步壁纸呀! 一个git pull 命令所有之前保存的图片就都来了!!
在node内使用git命令行,我们又需要一个模块child_process,这个模块是node自带的,可以直接使用。
const childProcess = require('child_process'); const cmd = (c) => c; const shell = 'bash'; const config = { env: { NODE_ENV: 'production', encoding: 'utf8', }, shell, }; const exec = (c) => { return new Promise((resolve, reject) => { childProcess.exec(c, config, (err, stdout, stderr) => { if (err) { reject(err); } else { resolve(stdout, stderr); } }); }); }; console.log('Deploy start.'); exec(cmd('git status')) .then(() => exec(cmd('git add .'))) .then(() => exec(cmd('git commit -m "ss"'))) .then(() => exec(cmd('git push -u origin master'))) .then(() => console.log('Deploy end.')) .catch(err => { console.error(err); });
这里的代码略微多了一点,但其实也很简单,就是让node去执行命令行,所有的命令行都在最下面。
将代码放置服务器运行,执行request改为如下:
const request = require('request'); const fs = require('fs'); const path = require('path'); request.get('http://cn.bing.com/HPImageArchive.aspx?format=js&idx=0&n=1&mkt=zh-CN', (error, response, body) => { const img = JSON.parse(body).images[0]; const arr = img.url.split('/'); const str = arr[arr.length - 1]; request(img.url).pipe(fs.createWriteStream(path.join('./img', str))); setTimeout(() => { require('./cmd.js'); }, 20000); console.log(`${new Date()}${str} is ok!`); });
这里的20s延迟是为了确保fs将文件保存完再进行git上传的一种简单的处理方式。当然还有其他解决方案,这样粗暴的解决只是因为这是个定时任务,对时间没有什么要求。