// ==UserScript==
// @name BiliBili稿件批量举报
// @namespace https://www.zhihu.com/question/46667028/answer/102445298
// @version 0.1.4
// @description BiliBili屎太多,黑名单不够用了,我很痛苦,于是写了这个脚本尝试将痛苦转移到发布视频的人身上,我准备了三个举报理由,点击按钮即可切换
// @author You
// @match https://space.bilibili.com/*
// @grant GM_setValue
// @grant GM_getValue
// @grant GM_xmlhttpRequest
// @grant GM_registerMenuCommand
// @grant GM_unregisterMenuCommand
// @connect api.bilibili.com
// @connect www.bilibili.com
// @run-at document-end
// ==/UserScript==
// 存储三个profile的举报理由和tid
const profiles = [
{
tid: 10014,
reason: '色情视频,色情游戏,视频侮辱国家领导人,宣扬“台独”,有政治隐喻'
},
{
tid: 10018,
reason: '视频内容是色情游戏,用评论和置顶动态贩卖色情内容盈利'
},
{
tid: 10014, // 占位备用
reason: '发布低俗图文及视频信息,或诱导他人私聊并推介线下色情服务;在账号资料、评论等环节,发布性暗示信息。利用黑话暗语、谐音词发布色情低俗动漫、视频、小说、游戏以及其他违法违规信息'
}
];
let currentProfileIndex = 0; // 初始化当前使用的profile索引
function switchProfile() {
currentProfileIndex = (currentProfileIndex + 1) % profiles.length;
updateDiagnosticInfo(`已切换至理由 ${currentProfileIndex + 1}
`);
}
// 在页面上创建切换profile的按钮
function addProfileSwitchButton() {
const switchButton = document.createElement('button');
switchButton.textContent = '切换理由';
switchButton.style.position = 'fixed';
switchButton.style.top = '60px';
switchButton.style.right = '150px';
switchButton.style.zIndex = '9999';
switchButton.onclick = function() {
switchProfile();
};
document.body.appendChild(switchButton);
}
// Create floating window with scrollable content
const floatingWindow = document.createElement('div');
floatingWindow.style.position = 'fixed';
floatingWindow.style.top = '90px';
floatingWindow.style.right = '20px';
floatingWindow.style.zIndex = '9999';
floatingWindow.style.background = 'white';
floatingWindow.style.border = '1px solid #ccc';
floatingWindow.style.padding = '10px';
floatingWindow.style.maxWidth = '340px';
floatingWindow.style.overflow = 'auto'; // Add overflow property for scrolling
floatingWindow.style.height = '200px'; // Set a height for the window
floatingWindow.style.scrollBehavior = 'smooth'; // Enable smooth scrolling
document.body.appendChild(floatingWindow);
// Create diagnostic info container
const diagnosticInfo = document.createElement('div');
floatingWindow.appendChild(diagnosticInfo);
// Function to scroll to the bottom of the floating window
function scrollToBottom() {
floatingWindow.scrollTop = floatingWindow.scrollHeight;
// Scroll the last element into view
const lastElement = floatingWindow.lastElementChild;
if (lastElement) {
lastElement.scrollIntoView({ behavior: 'smooth', block: 'end' });
}
}
// Updating the diagnosticInfo.innerHTML with the scroll to bottom
function updateDiagnosticInfo(content) {
diagnosticInfo.innerHTML += content;
scrollToBottom();
}
let delayInMilliseconds = 2100; // 设置延迟时间
// 更新 sendReportRequest 函数,在显示完最后一次举报返回值后显示“本页全部举报完成”,然后调用 clickPreviousPageButton 函数
function sendReportRequest() {
const mid = window.location.href.match(/bilibili.com\/(\d+)\/video/)[1];
const csrf = getCsrf();
const xhr = new XMLHttpRequest();
xhr.open("POST", 'https://space.bilibili.com/ajax/report/add', true);
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhr.onload = function () {
const decodedResponse = JSON.parse(decodeURIComponent(this.response));
updateDiagnosticInfo(`举报请求返回值:${Object.keys(decodedResponse).map(key => `${key}: ${decodedResponse[key]}`).join(', ')}
`);
// Call the existing functionality after the report request with a delay
setTimeout(() => {
getPageAllVideoAid();
}, delayInMilliseconds);
};
xhr.send(`mid=${mid}&reason=1%2C3%2C2&reason_v2=3&csrf=${csrf}`);
}
function addButton() {
// Existing button creation code remains unchanged
// Add a call to sendReportRequest before calling the existing functionality
const button = document.createElement('button');
button.textContent = '自动举报所有稿件';
button.style.position = 'fixed';
button.style.top = '60px';
button.style.right = '20px';// 更新 sendReportRequest 函数,在显示完最后一次举报返回值后显示“本页全部举报完成”,然后调用 clickPreviousPageButton 函数
function sendReportRequest() {
const mid = window.location.href.match(/bilibili.com\/(\d+)\/video/)[1];
const csrf = getCsrf();
const xhr = new XMLHttpRequest();
xhr.open("POST", 'https://space.bilibili.com/ajax/report/add', true);
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhr.onload = function () {
const decodedResponse = JSON.parse(decodeURIComponent(this.response));
updateDiagnosticInfo(`举报请求返回值:${Object.keys(decodedResponse).map(key => `${key}: ${decodedResponse[key]}`).join(', ')}
`);
// Call the existing functionality after the report request with a delay
setTimeout(() => {
getPageAllVideoAid();
}, delayInMilliseconds);
};
xhr.send(`mid=${mid}&reason=1%2C3%2C2&reason_v2=3&csrf=${csrf}`);
}
button.style.zIndex = '9999';
button.onclick = function() {
sendReportRequest();
};
document.body.appendChild(button);
}
GM_registerMenuCommand("自动举报所有稿件", fuckBilibiliShitVideo);
let csrfText = '';
function getCsrf() {
if (csrfText === '') {
const cook = document.cookie.match(/bili_jct=(.*?);/) ?? [];
if (cook.length === 2) {
csrfText = cook[1];
}
}
return csrfText;
}
function clickPreviousPageButton() {
setTimeout(() => {
updateDiagnosticInfo('本页全部举报成功
');
const previousPageButton = document.querySelector('.be-pager-prev');
if (!previousPageButton) {
const errorMessage = document.createElement('div');
updateDiagnosticInfo('未找到上一页按钮
');
errorMessage.textContent = '未找到上一页按钮';
errorMessage.style.color = 'red';
document.body.appendChild(errorMessage);
return; // 提前结束函数执行
} else if (previousPageButton.classList.contains('be-pager-disabled')) {
const errorMessage = document.createElement('div');
errorMessage.textContent = '上一页按钮已被禁用';
updateDiagnosticInfo('上一页按钮已被禁用
');
errorMessage.style.color = 'red';
document.body.appendChild(errorMessage);
return; // 提前结束函数执行
} else {
previousPageButton.querySelector('a').click();
setTimeout(fuckBilibiliShitVideo, 2500);
}
}, 500);
}
let encounteredError352 = false; // 添加一个全局变量来跟踪是否遇到了错误 -352
let reportCount = 0; // 添加一个变量用于记录举报次数
function fuckVideo(aid) {
reportCount++; // 每次举报增加序号
const profile = profiles[currentProfileIndex];
updateDiagnosticInfo(`开始举报稿件 ${reportCount},aid: ${aid}
`);
const xhr = new XMLHttpRequest();
xhr.open("POST", 'https://api.bilibili.com/x/web-interface/appeal/v2/submit', true);
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhr.withCredentials = true;
xhr.onload = function () {
const responseJson = JSON.parse(this.response);
if (responseJson.code === -352) {
updateDiagnosticInfo('遇到错误 -352,请完成人机验证
');
encounteredError352 = true;
} else {
updateDiagnosticInfo(`举报结果:${this.response}
`);
}
};
xhr.send(`aid=${aid}&attach=&block_author=false&csrf=${getCsrf()}&desc=${encodeURIComponent(profile.reason)}&tid=${profile.tid}`);
}
async function getVideoAid(id) {
return new Promise((resolve, reject) => { // 添加promise
if (encounteredError352) { // 如果遇到错误 -352
updateDiagnosticInfo('遇到错误 -352,请点击“继续”按钮以继续代码执行
');
// 暂停执行,并等待点击“继续”按钮
const continueButton = document.createElement('button');
continueButton.textContent = '继续';
continueButton.style.position = 'fixed';
continueButton.style.top = '60px';
continueButton.style.right = '235px';
continueButton.style.zIndex = '9999';
continueButton.onclick = function() {
encounteredError352 = false; // 点击“继续”按钮后,将变量值改为false
resolve(null); // 继续执行并返回null
continueButton.remove(); // 移除“继续”按钮
};
document.body.appendChild(continueButton);
} else {
GM_xmlhttpRequest({
url: `https://www.bilibili.com/video/${id}/?spm_id_from=333.999.0.0`,
method: "GET",
headers: {
'Cookie': document.cookie // Pass the cookies from the page to the request
},
onload: function (response) {
const aid = response.responseText.match(/"aid":(\d+)/);
if (aid) {
updateDiagnosticInfo(`成功获取到稿件,aid: ${aid[1]}
`);
resolve(aid[1]);
} else {
updateDiagnosticInfo('无法获取稿件 aid
');
resolve(null);
}
}
});
}
});
}
async function getPageAllVideoAid() {
const idList = [...document.querySelectorAll('.list-list .list-item')].map((dom) => dom.getAttribute('data-aid'));
updateDiagnosticInfo(`获取到 ${idList.length} 个稿件
`);
for (let index = 0; index < idList.length; index++) {
const aid = await getVideoAid(idList[index]);
if (aid) {
// Add a delay before calling fuckVideo
await new Promise(resolve => setTimeout(resolve, delayInMilliseconds));
fuckVideo(aid);
}
}
clickPreviousPageButton(); // 在所有操作完成后调用点击上一页按钮的函数
}
async function fuckBilibiliShitVideo() {
reportCount = 0; // 每次重新运行函数时重置序号
updateDiagnosticInfo('开始自动举报所有稿件
');
await getPageAllVideoAid();
// 执行其他操作...
}
// 添加一个按钮,点击后将链接中的数字写入用户剪贴板
function addCopyIdButton() {
const userId = window.location.href.match(/bilibili.com\/(\d+)\//)[1]; // 获取链接中的数字部分
const copyButton = document.createElement('button');
copyButton.textContent = '复制用户ID';
copyButton.style.position = 'fixed';
copyButton.style.top = '60px'; // 调整按钮位置
copyButton.style.right = '300px';
copyButton.style.zIndex = '9999';
copyButton.onclick = function() {
navigator.clipboard.writeText(`${userId}\n`); // 将数字写入剪贴板并加上换行符
updateDiagnosticInfo(`用户ID ${userId} 已复制到剪贴板`);
};
document.body.appendChild(copyButton);
}
// 在页面加载完成后添加复制用户ID的按钮
window.onload = function() {
addButton(); // 添加举报按钮
addProfileSwitchButton(); // 添加切换profile的按钮
addCopyIdButton(); // 添加复制用户ID的按钮
};