B站用户视频批量举报助手实验性
// ==UserScript==
// @name B站用户视频批量举报助手实验性
// @namespace http://tampermonkey.net/
// @version 1.0 Beta
// @description 通过用户UID批量举报其全部视频
// @author DeathReaper
// @match https://www.bilibili.com/*
// @grant GM_xmlhttpRequest
// @grant GM_cookie
// @grant GM_notification
// @grant GM_setValue
// @grant GM_getValue
// @grant GM_registerMenuCommand
// @connect bilibili.com
// @require https://cdn.jsdelivr.net/npm/jquery@3.6.0/dist/jquery.min.js
// ==/UserScript==
(function() {
'use strict';
// 配置参数
const DELAY_SECONDS = 10; // 每次举报间隔(秒)
const MAX_PAGE_SIZE = 50; // 每次获取视频数量
const MAX_RETRY = 2; // 单视频最大重试次数
// API配置
const USER_VIDEO_API = "https://api.bilibili.com/x/space/wbi/arc/search";
const REPORT_API = "https://api.bilibili.com/x/gaia-video-api/justice/commit";
// 全局状态
let isRunning = false;
let currentTask = null;
// 获取用户所有视频
async function getUserVideos(uid) {
let page = 1;
const videos = [];
while (true) {
const url = `${USER_VIDEO_API}?mid=${uid}&ps=${MAX_PAGE_SIZE}&pn=${page}`;
const result = await fetchAPI(url);
if (result.code !== 0 || !result.data.list.vlist) break;
videos.push(...result.data.list.vlist.map(v => v.aid));
if (result.data.list.vlist.length < MAX_PAGE_SIZE) break;
page++;
await delay(2000); // 分页请求间隔
}
return videos;
}
// 执行批量举报
async function batchReport(uid) {
if (isRunning) {
GM_notification("已有任务正在运行!", "警告");
return;
}
isRunning = true;
const startTime = Date.now();
try {
// 步骤1:获取用户所有视频
GM_notification("开始获取用户视频列表...", "信息");
const aids = await getUserVideos(uid);
if (aids.length === 0) {
GM_notification("该用户没有发布视频", "完成");
return;
}
// 步骤2:逐条举报
GM_notification(`发现${aids.length}个视频,开始处理...`, "信息");
let successCount = 0;
for (const [index, aid] of aids.entries()) {
if (!isRunning) break;
let retry = 0;
while (retry <= MAX_RETRY) {
const result = await sendReport(aid);
if (result.code === 0) {
successCount++;
break;
}
retry++;
}
// 进度提示
const progress = ((index + 1) / aids.length * 100).toFixed(1);
GM_notification(
`进度: ${progress}%\n` +
`成功: ${successCount}/${aids.length}\n` +
`当前视频: av${aid}`,
"处理中",
2
);
await delay(DELAY_SECONDS * 1000);
}
// 生成报告
const timeUsed = Math.round((Date.now() - startTime)/1000);
GM_notification(
`任务完成!\n` +
`成功率: ${successCount}/${aids.length}\n` +
`耗时: ${timeUsed}秒`,
"最终报告"
);
} finally {
isRunning = false;
}
}
// 核心工具函数
async function fetchAPI(url) {
return new Promise(resolve => {
GM_xmlhttpRequest({
method: "GET",
url: url,
headers: {
"Referer": location.href,
"Origin": "https://www.bilibili.com"
},
onload: res => resolve(JSON.parse(res.responseText)),
onerror: () => resolve({ code: -500 })
});
});
}
async function sendReport(aid) {
const csrf = await getCSRFToken();
if (!csrf) return { code: -403 };
return new Promise(resolve => {
GM_xmlhttpRequest({
method: "POST",
url: REPORT_API,
data: `aid=${aid}&reason_id=1&csrf=${csrf}`,
headers: {
"Content-Type": "application/x-www-form-urlencoded",
"Referer": "https://www.bilibili.com/"
},
onload: res => resolve(JSON.parse(res.responseText)),
onerror: () => resolve({ code: -500 })
});
});
}
// 用户交互界面
function createUI() {
const panel = $(`
<div id="batch-report-panel" style="
position: fixed;
right: 20px;
bottom: 70px;
background: white;
padding: 15px;
box-shadow: 0 2px 10px rgba(0,0,0,0.2);
z-index: 99999;
width: 300px;
">
<h3 style="margin:0 0 10px 0">批量举报设置</h3>
<input type="text" id="target-uid" placeholder="输入用户UID" style="width:100%; margin-bottom:10px">
<button id="start-btn" style="width:100%; padding:5px">开始执行</button>
<button id="stop-btn" style="width:100%; margin-top:5px; display:none">停止任务</button>
<div id="status" style="margin-top:10px; font-size:0.9em"></div>
</div>
`);
// 事件绑定
panel.find("#start-btn").click(async () => {
const uid = panel.find("#target-uid").val();
if (!/^\d+$/.test(uid)) {
updateStatus("UID必须为纯数字!", "red");
return;
}
panel.find("#start-btn").hide();
panel.find("#stop-btn").show();
updateStatus("任务启动中...", "blue");
currentTask = batchReport(uid);
await currentTask;
panel.find("#stop-btn").hide();
panel.find("#start-btn").show();
});
panel.find("#stop-btn").click(() => {
isRunning = false;
updateStatus("用户主动终止任务", "orange");
});
function updateStatus(text, color) {
panel.find("#status").html(`<span style="color:${color}">${text}</span>`);
}
$("body").append(panel);
}
// 辅助函数
function delay(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
async function getCSRFToken() {
return new Promise(resolve => {
GM_cookie.list({ domain: ".bilibili.com", name: "bili_jct" }, cookies => {
resolve(cookies[0]?.value || null);
});
});
}
// 初始化
GM_registerMenuCommand("打开批量举报面板", () => {
if (!$("#batch-report-panel").length) createUI();
});
setTimeout(() => {
if (location.hostname === 'space.bilibili.com') createUI();
}, 3000);
})();