BiliBili稿件批量举报

BiliBili屎太多,黑名单不够用了,我很痛苦,于是写了这个脚本尝试将痛苦转移到发布视频的人身上,我准备了三个举报理由,点击按钮即可切换

Cài đặt script này?
Script được tác giả gợi ý

Bạn có thế thích 自动跳转到视频页面

Cài đặt script này
// ==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}<br>`);
}

// 在页面上创建切换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(`举报请求返回值:<strong>${Object.keys(decodedResponse).map(key => `${key}: ${decodedResponse[key]}`).join(', ')}</strong><br>`);
    // 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(`举报请求返回值:<strong>${Object.keys(decodedResponse).map(key => `${key}: ${decodedResponse[key]}`).join(', ')}</strong><br>`);
    // 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('<strong style="font-size: 2em">本页全部举报成功</strong><br>');
    const previousPageButton = document.querySelector('.be-pager-prev');

    if (!previousPageButton) {
      const errorMessage = document.createElement('div');
      updateDiagnosticInfo('<strong style="font-size: 2em; color: red;">未找到上一页按钮</strong><br>');
      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('<strong style="font-size: 2em; color: red;">上一页按钮已被禁用</strong><br>');
      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(`开始举报稿件 <span style="color: red; font-weight: bold;">${reportCount}</span>,aid: ${aid}<br>`);
  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('<strong style="font-size: 2em; color: red;">遇到错误 -352,请完成人机验证</strong><br>');
      encounteredError352 = true;
    } else {
      updateDiagnosticInfo(`举报结果:<strong>${this.response}</strong><br>`);
    }
  };
  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,请点击“继续”按钮以继续代码执行<br>');
      // 暂停执行,并等待点击“继续”按钮
      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]}<br>`);
            resolve(aid[1]);
          } else {
            updateDiagnosticInfo('无法获取稿件 aid<br>');
            resolve(null);
          }
        }
      });
    }
  });
}
async function getPageAllVideoAid() {
  const idList = [...document.querySelectorAll('.list-list .list-item')].map((dom) => dom.getAttribute('data-aid'));
  updateDiagnosticInfo(`获取到 ${idList.length} 个稿件<br>`);
  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('开始自动举报所有稿件<br>');
  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的按钮
};