由于vercel域名国内无法正常访问,建议自建vercel api然后绑定域名使用。

BUG修复

22-08-14:修复widget.yml文件代码,因为我的疏忽,把bottom写成了buttom(不是因为英语差,绝对不是),导致不显示微博卡片。已有两个用户中招,I am very sorry.

前言

原文https://blog.eurkon.com/post/38b005e1.html
虽然这样可以实现,但是我感觉他的操作太麻烦了(可能因为之前不能自定义侧边栏),所以我就稍微进行了修改。

我的博客使用的是Butterfly主题,其他主题自行移植(就是引入css和js而已)

准备工作

1. 新建侧边栏

官方文档:https://butterfly.js.org/posts/ea33ab97/,想要了解更多可以查看这篇文章。

打开_data文件夹,创建一个widget.yml文件,在里面粘贴如下代码:

1
2
3
4
5
6
7
8
# 这里填top表示所有地方都显示,bottom表示只在非文章页面显示,如主页等等
bottom:
- class_name:
id_name: weibo
name: 微博热搜
icon: fa-brands fa-weibo
order: 1
html: <link rel="stylesheet" href="/css/weibo.css"><div id="weiboContent"><img src="https://www.leonus.cn/img/loading.gif"></div><script src="/js/weibo.js"></script> # 注意这里,我放了一个加载图片,在加载之前会显示,你可以选择删除或者放一个加载图片。

2.创建weibo.css文件

不会css和js文件创建和引入的参考:Hexo 博客添加自定义 css 和 js 文件

注意,我们只需要创建文件就可以,上面已经引入了

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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92

.weibo-new {
background: #ff3852
}

.weibo-hot {
background: #ff9406
}

.weibo-jyzy {
background: #ffc000
}

.weibo-recommend {
background: #00b7ee
}

.weibo-adrecommend {
background: #febd22
}

.weibo-friend {
background: #8fc21e
}

.weibo-boom {
background: #bd0000
}

.weibo-topic {
background: #ff6f49
}

.weibo-topic-ad {
background: #4dadff
}

.weibo-boil {
background: #f86400
}

#weibo .item-content {
text-align: center;
}

#weibo-container {
width: 100%;
height: 140px;
font-size: 95%;
overflow-y: auto;
-ms-overflow-style: none;
scrollbar-width: none
}

.weibo-list-item {
display: flex;
flex-direction: row;
justify-content: space-between;
flex-wrap: nowrap
}

.weibo-title {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
margin-right: auto
}

.weibo-num {
float: right
}

.weibo-hotness {
display: inline-block;
padding: 0 6px;
transform: scale(.8) translateX(-3px);
color: #fff;
border-radius: 8px
}

#weibo-container a {
color: #555;
}

[data-theme='dark'] #weibo-container a {
color: rgba(255, 255, 255, 0.7);
}

/* 隐藏滚动条 */
#weibo-container::-webkit-scrollbar{
display: none;
}

创建weibo.js文件

js方面有两种方式选择,各有利弊,根据自身情况选择

一、使用现成

现成的vercel api,创建js文件就能用:

  • 优点:直接用
  • 缺点:速度慢,要加载两秒左右

创建weibo.js

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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
// 如果你开启了在手机端显示侧边栏,可以将下面这行代码注释,开启下面的weibo();
try { if (document.getElementById('weibo').clientWidth) weibo(); } catch (error) {}
// weibo();

function weibo() {
let hotness = {
'爆': 'weibo-boom',
'热': 'weibo-hot',
'沸': 'weibo-boil',
'新': 'weibo-new',
'荐': 'weibo-recommend',
'影': 'weibo-jyzy',
'剧': 'weibo-jyzy',
'综': 'weibo-jyzy'
}
let html = '<div id="weibo-container">'
let data = JSON.parse(localStorage.getItem('weibo'));
let nowTime = Date.now();
let ls;
if (data == null || nowTime - data.time > 600000) { // 600000为缓存时间,即10分钟,避免频繁请求,加快本地访问速度。
getData();
return
} else {
ls = JSON.parse(data.ls)
};
for (let item of ls) {
html += '<div class="weibo-list-item"><div class="weibo-hotness ' + hotness[(item.hot || '荐')] + '">' + (item.hot || '荐') + '</div>' +
'<span class="weibo-title"><a title="' + item.title + '"href="' + item.url + '" target="_blank" rel="external nofollow noreferrer">' + item.title + '</a></span>' +
'<div class="weibo-num"><span>' + item.num + '</span></div></div>'
}
html += '</div>';
document.getElementById('weiboContent').innerHTML = html;
}

function getData() {
fetch('https://weibo-top-api.vercel.app/api').then(data => data.json()).then(data => {
data = { time: Date.now(), ls: JSON.stringify(data) }
localStorage.setItem('weibo', JSON.stringify(data))
}).then(weibo);
}

二、自建api

  • 优点:速度快,只需要两百毫秒左右。
  • 缺点:麻烦
    原作者是使用的python弄的,项目地址:https://github.com/Eurkon/weibo-top-api
    然后我把它弄成了node的,代码如下:

因为某某某访台的原因,微博炸了,api获取不到内容报错停了。
于是增加了一个try catch让代码更的健壮,已在index代码内更新。
如果你是使用的自建api,可以在前端weibo.js添加一个错误处理,如下:

1
2
3
4
5
6
7
8
9
10
function getData() {
fetch('https://api.leonus.cn/weibo').then(data => data.json()).then(data => {
+ if (data == '0') {
+ document.getElementById('weiboContent').innerHTML = '获取微博热搜失败'
+ return
+ }
data = { time: Date.now(), ls: JSON.stringify(data) }
localStorage.setItem('weibo', JSON.stringify(data))
}).then(weibo);
}

package.json

1
2
3
4
5
6
7
8
9
10
11
12
13
{
"name": "api",
"main": "index.js",
"scripts": {
"build": "node index.js"
},
"license": "ISC",
"dependencies": {
"@vercel/node": "^2.4.4",
"axios": "^0.27.2",
"express": "^4.18.1"
}
}

index.js

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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
const express = require('express');
const axios = require('axios')

const app = express()

app.all('*', function(req, res, next) {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Headers', 'Content-Type');
res.header('Access-Control-Allow-Methods', '*');
res.header('Content-Type', 'application/json;charset=utf-8');
next();
});

app.get('/weibo', async(req, res) => {
try {
let data = await get_data();
res.send(data);
} catch (e) {
res.send('0');
}
})

async function get_data() {
let dataList = []
let { data } = await axios.get('https://weibo.com/ajax/side/hotSearch');
let data_json = data.data.realtime
let jyzy = {
'电影': '影',
'剧集': '剧',
'综艺': '综',
'音乐': '音'
};

for (let i = 0; i < data_json.length; i++) {
let hot = ''

if ('is_ad' in data_json[i] == true) {
continue;
}
if ('flag_desc' in data_json[i] == true) {
hot = jyzy[data_json[i]['flag_desc']]
}
if ('is_boom' in data_json[i] == true) {
hot = '爆'
}
if ('is_hot' in data_json[i] == true) {
hot = '热'
}
if ('is_fei' in data_json[i] == true) {
hot = '沸'
}
if ('is_new' in data_json[i] == true) {
hot = '新'
}

let dic = {
'title': data_json[i]['note'],
'url': 'https://s.weibo.com/weibo?q=%23' + data_json[i]['word'] + '%23',
'num': data_json[i]['num'],
'hot': hot
}

dataList.push(dic)
}
return dataList
}



app.listen(3000)

部署到服务器

打开宝塔面板,在wwwroot下新建一个目录,然后新建 index.jspackage.json 并填写以上代码。

新建文件

建好之后切到网站页面,依次点击 node项目 > 新建node项目,然后填写配置,没有node的先安装node。

  • 项目目录:刚才创建的目录
  • 项目端口:随意先一个不常用端口,别忘了放行。
  • 绑定域名:随便绑一个你的域名,别忘了解析。
    建议申请并配置一下ssl,有的网站不能使用http。
  • 其他:默认即可
配置node

提交之后等待包安装完成就行,新建完成之后你可以通过设置来配置管理项目。

创建weibo.js

内容和上面直接使用vercel api的完全一样。
只不过需要修改api地址,即:https://weibo-top-api.vercel.app/api改成https://你的域名/weibo