B 站评论提取脚本及分析提示词

一直没有将音视频当作严肃的信息获取媒介,忽略听视觉从音视频提取信息无疑买椟还珠。局限于「文字」带来的「信息」,显然以文字本身作为载体的内容要高效得多。

新年的内容消费行动建议提到目前 AI 总结类工具已经完全可用,可以反过来,作为了解是否值得阅读的工具。一些知识类、观点类的视频可以提取文字稿利用 AI 总结分析。

一个好的学习方式是找到我们欣赏的人并 hacking 他们公开发表的一切。于是我打算趁着假期对该建议的作者Lunamos自己用此建议过一遍。

其它方面技术性细节不提。由于 Lunamos 自己,以及观众也在评论区留下不少有趣的内容,我尝试写了个脚本一键提取并交由 AI 筛选。

油猴脚本

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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
// ==UserScript==
// @name B站视频评论一键复制
// @namespace http://tampermonkey.net/
// @version 0.3
// @description 一键复制 Bilibili 视频评论(用户名 + 内容)
// @match https://www.bilibili.com/video/*
// @grant GM_setClipboard
// @run-at document-idle
// ==/UserScript==

(function () {
'use strict';

/* ---------- 工具函数 ---------- */
function getTextDeep(el) {
if (!el) return '';
if (el.nodeType === Node.TEXT_NODE) {
return el.textContent.trim();
}
return Array.from(el.childNodes)
.map(getTextDeep)
.join(' ')
.replace(/\s+/g, ' ')
.trim();
}

function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}

/* ---------- 核心提取逻辑 ---------- */
async function extractAllComments() {
const result = [];

const biliComments = document.querySelector('bili-comments');
if (!biliComments?.shadowRoot) {
alert('未找到评论容器,请确认在视频播放页');
return result;
}

// 等待评论加载
await sleep(1500);

const threads = biliComments.shadowRoot.querySelectorAll(
'bili-comment-thread-renderer'
);

threads.forEach(thread => {
if (!thread.shadowRoot) return;

const renderer = thread.shadowRoot.querySelector(
'bili-comment-renderer#comment'
);
if (!renderer?.shadowRoot) return;

// 用户名
let username = '';
const userInfo = renderer.shadowRoot.querySelector('bili-comment-user-info');
if (userInfo?.shadowRoot) {
const nameBox = userInfo.shadowRoot.querySelector('#user-name');
username = getTextDeep(nameBox);
}

// 评论内容
let content = '';
const contentDiv = renderer.shadowRoot.querySelector('#content');
if (contentDiv) {
const richText = contentDiv.querySelector('bili-rich-text');
if (richText?.shadowRoot) {
const contents = richText.shadowRoot.querySelector('#contents');
content = getTextDeep(contents);
}
}

if (username || content) {
result.push(`${username}${content}`);
}
});

return result;
}

/* ---------- UI 按钮 ---------- */
function createButton() {
const btn = document.createElement('button');
btn.innerText = '📋 一键复制评论';
Object.assign(btn.style, {
position: 'fixed',
top: '80px',
right: '20px',
zIndex: '99999',
padding: '10px 14px',
background: '#fb7299',
color: '#fff',
border: 'none',
borderRadius: '8px',
cursor: 'pointer',
fontSize: '14px',
boxShadow: '0 2px 8px rgba(0,0,0,.2)'
});

btn.onclick = async () => {
btn.innerText = '⏳ 正在提取...';
const comments = await extractAllComments();

if (!comments.length) {
alert('未提取到评论,请确认评论已加载');
btn.innerText = '📋 一键复制评论';
return;
}

const text = comments.join('\n\n');
GM_setClipboard(text);

btn.innerText = `✅ 已复制 ${comments.length} 条评论`;
setTimeout(() => {
btn.innerText = '📋 一键复制评论';
}, 2000);
};

document.body.appendChild(btn);
}

/* ---------- 初始化 ---------- */
window.addEventListener('load', () => {
setTimeout(createButton, 1000);
});
})();

评论筛选提示词

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
你是一个 B 站内容分析师。

下面是一段 Bilibili 视频的评论数据,每条格式固定为:

用户:评论内容

请完成以下任务:

整体分析

用户的主要情绪(正面 / 中性 / 负面)

讨论的核心话题

是否有明显争议或风险

提取有价值的评论

定义「有价值」:

包含实质性观点、有效反馈、建设性建议、补充信息、二次创作线索、典型情绪代表

排除:单纯刷表情、无意义刷屏、「前排」「沙发」「打卡」等低信息量内容

输出格式(必须严格遵守)

## 一、整体分析

(简要总结)## 二、有价值的评论

用户:评论内容

用户:评论内容

用户:评论内容

请确保:

「有价值的评论」部分只输出用户和评论原文

不修改、不总结、不缩写评论内容

每行一条,格式统一为:用户:评论