博客首页搭建记录

简单记录下网站首页的搭建过程。

背景

自从网站域名备案成功下来,一直以来都没想好首页应该怎么写。其实不是没想好,而是没有准备好首页的多张大背景图片应该存放在那,毕竟是最廉价的云服务器,应该本着勤俭持家的理念,能省就省嘛。不过还好,bing中文搜索官网的背景图片每天都会更新,于是萌生出了用nodejs爬别人图片的方法~

环境准备

首先,需要给服务器安装nodejs,centOS下通过yum install nodejs方式安装的nodejs是0.10版本的,根本无法写es6代码。没办法,只能通过源码安装了

1
2
3
4
5
6
wget http://nodejs.org/dist/v4.5.0/node-v4.5.0.tar.gz
tar -zxvf node-v4.5.0.tar.gz
cd node-v4.5.0
./configure
make
make install

ps:过程中如果报找不到g++编译器,则请先安装g++yum install gcc-c++
输入node -v检验是否安装成功
这里再顺便提一下安装npm的方法吧:
curl https://npmjs.com/install.sh | sudo sh
输入npm -v检验是否安装成功

爬图片

咳咳,接下来说到重点了,准备爬cn.bing.com网站的背景图片。

第一步

进入bing中文网址,cmd+alt+i打开开发者工具选项,Network选项,cmd+r刷新网页,找到网站的背景图片Ajax选项,这就是我们要找的Ajax请求url
ajax
返回的结果如下所示
ajax

第二步

github上有很多开源的nodeje抓包库,如superagent
而这次我所使用的是nodejs原生api
http.get(url, (res)=>{}): get请求
https.get(url, (res)=>{}): https方式
ps: 其实上面两种都是http(s).request(options, (res)=>{})的GET方式简化版,只是因为当前大部分网站都是GET请求方式。
通过上面的图片,我们此处使用http.get():

1
2
3
4
5
6
7
const http = require('http');
const ajaxUrl = 'http://cn.bing.com/HPImageArchive.aspx?format=js&idx=0&n=1';
http.get(ajaxUrl, (res) => {
res.on('data', (d) => {
console.log(d)
})
})

此处终端的打印出来的是buffer对象,所以我们需要将其转为字符串,然后转为json对象取到需要的图片url,代码如下:

1
2
const json = JSON.parse(d.toString());
const src = json.images[0].url;

上面中的src就是我们需要的图片url地址。

第三步

通过以上方式,虽然我们获取到了目标图片的url,但如何把它应用到首页还是个问题。
本人采取的方法是通过nodejs启动一个服务,返回目标字符串background-image:url(' + src + '),首页通过ajax请求之后添加到body的style对象上。
查看效果:https://qingguoing.com:3000
等等,有个坑,首页是通过nginx跑在80端口,而nodejs服务是跑在3000端口,于是就涉及到ajax跨域的问题。解决方法也很简单,nodejs设置返回头Access-Control-Allow-Origin: *。所以nodejs最终代码如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
const https = require('https');
const http = require('http');
const fs = require('fs');
const options = {
key: fs.readFileSync('./ssl/privkey1.pem'),
cert: fs.readFileSync('./ssl/fullchain1.pem')
};
const ajaxUrl = 'http://cn.bing.com/HPImageArchive.aspx?format=js&idx=0&n=1';
https.createServer(options, function(request, response) {
response.writeHead(200, {
'Content-Type': 'text/html',
'Access-Control-Allow-Origin': 'https://qingguoing.com'
});
http.get(ajaxUrl, (res) => {
res.on('data', (d) => {
const json = JSON.parse(d.toString());
const url = json.images[0].url;
response.write('background-image:url('+ url +')');
response.end();
})
})
}).listen(3000);
console.log('server is listening on the port 3000');

ps1: 个人网站采用的是https链接,ssl证书是通过letsencrypt免费生成。
ps2: ajax跨域头只设置了个人网站的首页,所以大家如果想按我这种穷屌丝方式爬去图片,还是去爬微软大厂的吧。既然都看到这了,相信对您来说,这些都是小菜一碟

最后

最后当然就是运行node程序了。不过如果你像我一样,通过终端命令远程连接到服务器端,那么你应该按照如下方式执行node命令:
node app.js&
此时开启的服务是后台跑起的,直接退出并不会终止已跑起的node程序

最后的最后

以下内容更新于2016-09-29

最近发现bing中文网似乎对数据抓取做了限制,也可能是因为我的node服务的问题,node https服务会偶尔中断,需要远程登录服务器重新跑一遍node,所以就通过request库加定时任务,每天0点执行图片抓取服务,将远程图片保存到本地。目前来看,效果还不错,而且首页的https协议也不会警告了。