Node.js 实现微博话题趋势查询接口教程

简介

本教程介绍如何使用 Node.js 搭建一个简单的 HTTP 服务,基于 Express 和 Axios 提供一个可以查询微博话题趋势的接口。用户可以通过 GET 请求指定关键词(search)和时间范围(time)获取相关数据。

功能概述

  • 技术栈:Express.js(搭建服务器)、Axios(发起 HTTP 请求)
  • 核心功能:实现一个 GET 接口 /search,通过 search 参数指定查询话题,通过 time 参数控制时间范围(如 1小时、1天、7天、30天)。
  • API 源地址:接口将数据请求重定向到微博的 AJAX 接口 https://m.s.weibo.com/ajax_topic/trend

代码结构

导入模块

1
2
const express = require('express'); // Express.js 用于搭建 Web 服务器
const axios = require('axios'); // Axios 用于发起 HTTP 请求

配置服务器

1.创建 Express 实例

2.定义服务器监听的端口号

1
2
const app = express();
const port = 3000; // 端口号
  • 接口参数:

      search(必填):查询的话题名称
      time(必填):时间范围(可选值为 6m, 24h, 7d, 30d)
    
  • 请求头:设置 User-Agent 和模拟的 Cookie

  • 核心功能:通过 Axios 将用户请求转发到微博的趋势 API,并返回结果。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
app.get('/search', async (req, res) => {
const { search, time } = req.query; // 获取参数

// 参数校验
if (!search || !time) {
return res.status(400).json({ error: '缺失参数' });
}

const headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36 Edg/131.0.0.0',
'Referer': `https://m.s.weibo.com/vtopic/detail_new?click_from=searchpc&q=${encodeURIComponent(search)}`,
'Cookie': 'YOUR_COOKIE_HERE', // 模拟微博登录
};

const url = `https://m.s.weibo.com/ajax_topic/trend?q=%23${encodeURIComponent(search)}%23&version=v1&time=${encodeURIComponent(time)}`;

try {
const response = await axios.get(url, { headers });
res.json(response.data); // 返回微博的响应数据
} catch (error) {
console.error('请求错误:', error);
res.status(500).json({ error: '连接失败' });
}
});

启动服务器

监听指定端口,并打印成功启动的提示信息

1
2
3
app.listen(port, () => {
console.log(`Server is running at http://localhost:${port}`);
});

运行

1.环境准备

  • 确保已安装 Node.js 和 npm。
  • 安装所需依赖:
1
npm install express axios

2. 保存代码

将上述代码保存到文件中,例如:weibo.js。

3. 启动服务

在终端运行以下命令

1
node weibo.js

启动后,服务将在 http://localhost:3000 运行。

4. 测试接口

可以使用浏览器或 Postman 测试接口

1
GET http://localhost:3000/search?search=你的关键词&time=24h

响应事例

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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
{
"code": "100000",
"msg": "success",
"data": {
"read": [
{
"time": "12:20",
"value": 1720255
},
{
"time": "12:30",
"value": 1827983
},
{
"time": "12:40",
"value": 1565867
},
{
"time": "12:50",
"value": 1526080
},
{
"time": "13:00",
"value": 1727448
},
{
"time": "13:10",
"value": 1442067
}
],
"me": [
{
"time": "12:20",
"value": 590
},
{
"time": "12:30",
"value": 506
},
{
"time": "12:40",
"value": 620
},
{
"time": "12:50",
"value": 702
},
{
"time": "13:00",
"value": 482
},
{
"time": "13:10",
"value": 505
}
],
"ori": [
{
"time": "12:20",
"value": 227
},
{
"time": "12:30",
"value": 237
},
{
"time": "12:40",
"value": 228
},
{
"time": "12:50",
"value": 202
},
{
"time": "13:00",
"value": 196
},
{
"time": "13:10",
"value": 168
}
],
"partake": [
{
"time": "12:20",
"value": 1863
},
{
"time": "12:30",
"value": 1390
},
{
"time": "12:40",
"value": 1708
},
{
"time": "12:50",
"value": 1796
},
{
"time": "13:00",
"value": 1602
},
{
"time": "13:10",
"value": 1426
}
]
}
}

完整代码

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
const express = require('express');
const axios = require('axios');
const app = express();
const port = 3000; // 端口号


// 设置一个 GET 请求接口,接收 'search' 和 'time' 参数
// time时间分为 '6m'(一小时) 、 '24h'(一天) 、 '7d'(七天) 、 '30d'(30天)

app.get('/search', async (req, res) => {
const { search, time } = req.query; // 获取 'search' 和 'time' 参数

if (!search || !time) {
return res.status(400).json({ error: '缺失参数' });
}

// 设置请求头
const headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36 Edg/131.0.0.0',
'Referer': `https://m.s.weibo.com/vtopic/detail_new?click_from=searchpc&q=${encodeURIComponent(search)}`,
'Cookie': 'UOR=,,cn.bing.com; SCF=AhdiEeakn2z6IN5MU7cDtG246Mhmbc18nPhHgxBoCz06tjrG1wkmZaUR4y4p_HxNQpH9G6hqDgFHOYtH34RFbJ8.; SINAGLOBAL=5171713576703.485.1729942839953; SUBP=0033WrSXqPxfM725Ws9jqgMF55529P9D9W5aeeFpz4KndOChmog8mPAP5JpX5KMhUgL.Foq41K.cSKn0ehB2dJLoIEBLxK-L12BL1h2LxKnLB.qL1-zLxK-L1hnLBoqLxKBLB.BL12Bt; ULV=1736402736564:143:3:2:456079883442.03986.1736402736509:1736067161257; XSRF-TOKEN=EdAXh5pUMjkwv_L7de42ATqM; ALF=1740287447; SUB=_2A25Kl1CHDeRhGeBH4lsX9SbPyziIHXVp7exPrDV8PUJbkNANLW3hkW1NQYOOUT_y3wuh61z48Yx5xXRLir4ij28W; WBPSESS=YnzsitvrOoYuPFo2q_z3Fe0GTmpq1le6wTCBS1Cd4pVBlG2ZrcXyzZScXy1UAEmrwdWgWQKE2Pgp8YWqp5PbrEpo9q2mNceoR-b7NcrPsHLgJrZqEBL2yejefWDF955Pi2kQxuP8qvpIOsESCLEFKw==',
};

// 构建请求的 URL
const url = `https://m.s.weibo.com/ajax_topic/trend?q=%23${encodeURIComponent(search)}%23&version=v1&time=${encodeURIComponent(time)}`;

try {
// 发送请求并获取响应
const response = await axios.get(url, { headers: headers });

// 如果请求成功,返回数据
res.json(response.data);
} catch (error) {
// 处理请求失败的情况
console.error('请求错误:', error);
res.status(500).json({ error: '连接失败' });
}
});

// 启动服务器
app.listen(port, () => {
console.log(`Server is running at http://localhost:${port}`);
});