Bilibili 按标签、标题、时长、UP主屏蔽视频

对 Bilibili.com 的视频卡片元素,以标题、UP 主、标签、双重标签、充电专属、收藏投币比、竖屏、时长、播放量、点赞率、视频分区、UP 主等级、UP 主粉丝数、UP 主简介、精选评论、置顶评论来判断匹配,添加覆盖叠加层或隐藏视频,隐藏或屏蔽热搜、附带去除广告等非视频元素的功能。

< 脚本 Bilibili 按标签、标题、时长、UP主屏蔽视频 的反馈

提问 / 留言

§
发布于:2025-07-23

非常好用,可以过滤掉很多垃圾视频,另外共享一下我这半年多写的一些屏蔽词的正则表达式,我自认为很有效的过滤掉很多广告、卖课等等的垃圾视频,其中关于编程、ai等等的割韭菜内容偏多,如果你要使用最好先筛选一下,避免误伤。使用方法:在 视频过滤 -> 标题关键词过滤,填入正则表达式内。 (表达式写法提示:以/开头和结尾,每行一个,其中用到两种屏蔽词,必须包含的词,和用|分割的任意词,没有用到复杂的写法,足够应付大多数场景了,也欢迎大佬共享一下更多有效屏蔽垃圾视频的表达式)

/(?=.*(付费|免费|最新版|专业版))(?=.*(课程|教程|教学|新手))(?=.*(从零|零基|基础|已被开除|冒死上传|完整版))(?=.*(全套|小白|内部|唱歌|剪辑|剪映))/
/(?=.*冒死上传)(?=.*(付费|免费教程))(?=.*(从零|零基|基础))/
/(?=.*(白嫖|不限速|领取))(?=.*(免费|年卡|会员|天|36|不限速))(?=.*(分享|体验|享受|安装|保姆级|教程))(?=.*(更新|网盘|扩容|夸克|vip|VIP))/
/(?=.*(最新|下载))(?=.*(百度|夸克)(?=.*(不限速|高速)))/
/(?=.*(PS|photoshop|ps|photoshop))(?=.*(安装包|安装|下载|资源))(?=.*免费)(?=.*教程)(?=.*最新版)/
/(?=.*(流量|WIFI|wifi))(?=.*破解)(?=.*密码)(?=.*(一秒|轻松|秒杀))(?=.*(Docker|Python|docor|python))/
/(?=.*(steam|epic))(?=.*(喜加一|免费入库|白嫖))(?=.*(激活码|豪华版|回馈活动|限时))/
/(?=.*最新版)(?=.*安装)(?=.*(VMware|vmware|虚拟机))/
/(?=.*喂饭)(?=.*大模型)(?=.*微调)(?=.*教程)/
/(?=.*(大模型|LLM|llm))(?=.*开源)(?=.*(最新|本地|部署))(?=.*(微调|训练))(?=.*(实操|手把手))/
/(?=.*保姆级)(?=.*入门)(?=.*实战)(?=.*(教程|课程))(?=.*(Docker|Python|docor|python))(?=.*(从零|零基|基础))(?=.*(掌握|学习))/
/(?=.*(llama|LLaMa|cursor|Cursor|deepseek|DeepSeek|openai|OpenAI|Qwen|qwen|chat|Chat|GPT|gpt|GPT4o|Dify|stable|diffusion|AIGC|绘画|SD))(?=.*(平替|免费|保姆级|手把手|最新|胎教级|免费使用|无任何限制|无限制|论文|小白|学会|分钟))(?=.*(本地|搭建|私有化|AI|ai|离线|微调|大模型|模型库|部署|国内|智能体|分析系统))(?=.*(最新|教程|详细教程|免翻|限制|国内|低成本|付费|免费|干货|自学|全网|最详细))/
/(?=.*(详细|激活|下载|一键))(?=.*安装)(?=.*教程)(?=.*(Docker|Python|docor|python))/
/(?=.*(抢票|wifi|车票))(?=.*(自动|黄牛|破解))(?=.*python)(?=.*(教程|脚本|代码))/
/(?=.*(python|C语言|cpp|rust|golan|lua))(?=.*(自动|自动化|动画片|漫画|退出IT|最全|最细|自学|清华|字节|pycharm|逼自己|墙裂推荐|强烈推荐|2025最强|2025最新|就够|还爽))(?=.*(教程|零基础|专业版|清华|字节|脚本|代码|最新版|终于|精通|通俗易懂|全B站|绝对是))/
/(?=.*冒死上传|重发|下架|死磕)(?=.*(python|保姆级|教程|零基础|付费|逼自己))(?=.*(干货|咬咬牙|白嫖))/
/(?=.*(暑假|月|日|天|分享|电脑))(?=.*(稳|赚|钱|接单|在家|简单|w))(?=.*(python|ai|编程|c#|java))/
/(?=.*(学编程|编程游戏))(?=.*(python|ai))(?=.*(死磕|学习|简单|入门|进阶))/
/(?=.*(屏蔽宽带|宽带|融合宽带))(?=.*(移动|联通|电信|低价|便宜))(?=.*(推荐|报装))/
/(?=.*模板示例关键词1)(?=.*关键词2)(?=.*(任意词1|任意词2))(?=.*(任意词1|任意词2))/
§
发布于:2025-07-25

太强了,没在b站泡个三年写不出这么多关键词。看这几个词就能想象视频封面了

§
发布于:2025-07-25

额,抱歉,同时打开了多个脚本的页面,突然想写个评论就写了发出来,然后发现发错了也删不了,这是另一个脚本的屏蔽词表达式,可能在这个脚本用不了我没有试过,评价错脚本了抱歉。

§
发布于:2025-09-20

世界因你而美好

§
发布于:2025-09-20

那我也来分享一个, 快速获取视频标签的脚本.

// ==UserScript==
// @name         B站卡片一键复制标签
// @namespace    https://github.com/
// @version      1.0
// @description  在指定视频卡片右下角添加按钮,点击复制该视频标签到剪贴板(基于脚本中获取标签的方法)
// @match        https://www.bilibili.com/*
// @match        https://space.bilibili.com/*
// @grant        GM_setClipboard
// @connect      api.bilibili.com
// @run-at       document-end
// ==/UserScript==

(function () {
  'use strict';

  const SELECTOR = 'div.pt-15px.flex.gap-x-5px.overflow-hidden.px-5px.mb-10px';
  const tagsCache = {};

  // av -> bv 转换(取自原脚本)
  function av2bv(aid) {
    const XOR_CODE = 23442827791579n;
    const MASK_CODE = 2251799813685247n;
    const MAX_AID = 1n << 51n;
    const BASE = 58n;
    const data = 'FcwAPNKTMug3GV5Lj7EJnHpWsx4tb8haYeviqBz6rkCy12mUSDQX9RdoZf';
    const bytes = ['B', 'V', '1', '0', '0', '0', '0', '0', '0', '0', '0', '0'];
    let bvIndex = bytes.length - 1;
    let tmp = (MAX_AID | BigInt(aid)) ^ XOR_CODE;
    while (tmp > 0) {
      bytes[bvIndex] = data[Number(tmp % BigInt(BASE))];
      tmp = tmp / BASE;
      bvIndex -= 1;
    }
    [bytes[3], bytes[9]] = [bytes[9], bytes[3]];
    [bytes[4], bytes[7]] = [bytes[7], bytes[4]];
    return bytes.join('');
  }

  function extractBv(card) {
    // 遍历 a 链接寻找 BV 或 av
    const anchors = card.querySelectorAll('a[href]');
    let bv = null;
    for (const a of anchors) {
      const href = a.href || '';
      // 匹配 BV
      const bvMatch = href.match(/\/(BV[0-9A-Za-z]+)/);
      if (bvMatch) {
        bv = bvMatch[1];
        break;
      }
      // 匹配 av
      const avMatch = href.match(/\/(av)(\d+)/i);
      if (avMatch) {
        try {
          bv = av2bv(avMatch[2]);
          break;
        } catch (e) {}
      }
      // 有时候 href 可能是相对路径 like /video/BVxxx
      const relMatch = (a.getAttribute('href') || '').match(/\/(BV[0-9A-Za-z]+)/);
      if (relMatch) {
        bv = relMatch[1];
        break;
      }
    }
    return bv;
  }

  async function fetchTags(bv) {
    if (!bv) return '';
    if (bv in tagsCache) return tagsCache[bv];
    try {
      const resp = await fetch(`https://api.bilibili.com/x/web-interface/view/detail/tag?bvid=${bv}`, { credentials: 'omit' });
      const j = await resp.json();
      let tags = '';
      if (j && Array.isArray(j.data)) {
        tags = j.data
          .map(t => t.tag_name.replace(/\s+/g, ''))
          .filter(Boolean)
          .join(',');
      } else if (j && j.data && Array.isArray(j.data.tags)) {
        // 兼容不同格式
        tags = j.data.tags.map(t => t.tag_name || t).filter(Boolean).join(', ');
      }
      tagsCache[bv] = tags;
      return tags;
    } catch (e) {
      tagsCache[bv] = '';
      return '';
    }
  }

  function copyToClipboard(text) {
    if (!text) return false;
    if (typeof GM_setClipboard === 'function') {
      try { GM_setClipboard(text); return true; } catch (e) {}
    }
    if (navigator.clipboard && navigator.clipboard.writeText) {
      return navigator.clipboard.writeText(text).then(() => true).catch(() => fallbackCopy(text));
    }
    return fallbackCopy(text);
  }

  function fallbackCopy(text) {
    try {
      const ta = document.createElement('textarea');
      ta.value = text;
      ta.style.position = 'fixed';
      ta.style.left = '-9999px';
      document.body.appendChild(ta);
      ta.select();
      document.execCommand('copy');
      document.body.removeChild(ta);
      return true;
    } catch (e) {
      return false;
    }
  }

  function showTempText(btn, msg, timeout = 1400) {
    const old = btn.innerText;
    btn.innerText = msg;
    setTimeout(() => { btn.innerText = old; }, timeout);
  }

  function addButtonToCard(card) {
    if (card.dataset.copyTagsBtnAdded) return;
    card.dataset.copyTagsBtnAdded = '1';
    card.style.position = card.style.position || 'relative';

    const btn = document.createElement('button');
    btn.type = 'button';
    btn.innerText = '📋';
    btn.className = 'gm-copy-tags-btn';
    Object.assign(btn.style, {
      position: 'absolute',
      bottom: '6px',
      right: '6px',
      zIndex: 999999,
      padding: '4px 8px',
      fontSize: '12px',
      background: '#4EA8DE',
      color: '#fff',
      border: 'none',
      borderRadius: '6px',
      cursor: 'pointer',
      boxShadow: '0 2px 6px rgba(0,0,0,0.2)'
    });

    btn.addEventListener('click', async (e) => {
      e.stopPropagation();
      e.preventDefault();
      btn.disabled = true;
      const bv = extractBv(card);
      if (!bv) {
        showTempText(btn, '未找到BV');
        btn.disabled = false;
        return;
      }
      const tags = await fetchTags(bv);
      if (tags) {
        const ok = await copyToClipboard(tags);
        showTempText(btn, ok ? '已复制' : '复制失败');
      } else {
        showTempText(btn, '无标签');
      }
      btn.disabled = false;
    });

    card.appendChild(btn);
  }

  function scanAndInject() {
    const cards = document.querySelectorAll(SELECTOR);
    cards.forEach(addButtonToCard);
  }

  // 初始化扫描
  scanAndInject();

  // 监听 DOM 变化以处理懒加载/动态加载的卡片
  const mo = new MutationObserver((mutations) => {
    for (const m of mutations) {
      if (m.addedNodes && m.addedNodes.length) {
        scanAndInject();
        break;
      }
    }
  });
  mo.observe(document.body, { childList: true, subtree: true });

})();
§
发布于:2025-09-20

上面的是在bili-gate插件上用的 重新弄了个适配原版的

// ==UserScript==
// @name         B站卡片一键复制标签(新版HTML适配)
// @namespace    https://github.com/
// @version      1.1
// @description  在新版视频卡片右下角添加按钮,点击复制视频标签到剪贴板
// @match        https://www.bilibili.com/*
// @grant        GM_setClipboard
// @connect      api.bilibili.com
// @run-at       document-end
// ==/UserScript==

(function () {
  'use strict';

  const SELECTOR = 'div.bili-video-card.is-rcmd';
  const tagsCache = {};

  function av2bv(aid) {
    const XOR_CODE = 23442827791579n;
    const MASK_CODE = 2251799813685247n;
    const MAX_AID = 1n << 51n;
    const BASE = 58n;
    const data = 'FcwAPNKTMug3GV5Lj7EJnHpWsx4tb8haYeviqBz6rkCy12mUSDQX9RdoZf';
    const bytes = ['B', 'V', '1', '0', '0', '0', '0', '0', '0', '0', '0', '0'];
    let bvIndex = bytes.length - 1;
    let tmp = (MAX_AID | BigInt(aid)) ^ XOR_CODE;
    while (tmp > 0) {
      bytes[bvIndex] = data[Number(tmp % BigInt(BASE))];
      tmp = tmp / BASE;
      bvIndex -= 1;
    }
    [bytes[3], bytes[9]] = [bytes[9], bytes[3]];
    [bytes[4], bytes[7]] = [bytes[7], bytes[4]];
    return bytes.join('');
  }

  function extractBv(card) {
    const a = card.querySelector('a.bili-video-card__image--link');
    if (!a) return null;
    const href = a.href || '';
    const bvMatch = href.match(/\/(BV[0-9A-Za-z]+)/);
    if (bvMatch) return bvMatch[1];
    const avMatch = href.match(/\/(av)(\d+)/i);
    if (avMatch) return av2bv(avMatch[2]);
    return null;
  }

  async function fetchTags(bv) {
    if (!bv) return '';
    if (tagsCache[bv]) return tagsCache[bv];
    try {
      const resp = await fetch(`https://api.bilibili.com/x/web-interface/view/detail/tag?bvid=${bv}`, { credentials: 'omit' });
      const j = await resp.json();
      let tags = '';
      if (j && Array.isArray(j.data)) {
        tags = j.data.map(t => t.tag_name.replace(/\s+/g, '')).filter(Boolean).join(',');
      } else if (j && j.data && Array.isArray(j.data.tags)) {
        tags = j.data.tags.map(t => t.tag_name || t).filter(Boolean).join(',');
      }
      tagsCache[bv] = tags;
      return tags;
    } catch (e) {
      tagsCache[bv] = '';
      return '';
    }
  }

  function copyToClipboard(text) {
    if (!text) return false;
    if (typeof GM_setClipboard === 'function') {
      try { GM_setClipboard(text); return true; } catch (e) {}
    }
    if (navigator.clipboard && navigator.clipboard.writeText) {
      return navigator.clipboard.writeText(text).then(() => true).catch(() => fallbackCopy(text));
    }
    return fallbackCopy(text);
  }

  function fallbackCopy(text) {
    try {
      const ta = document.createElement('textarea');
      ta.value = text;
      ta.style.position = 'fixed';
      ta.style.left = '-9999px';
      document.body.appendChild(ta);
      ta.select();
      document.execCommand('copy');
      document.body.removeChild(ta);
      return true;
    } catch (e) {
      return false;
    }
  }

  function showTempText(btn, msg, timeout = 1400) {
    const old = btn.innerText;
    btn.innerText = msg;
    setTimeout(() => { btn.innerText = old; }, timeout);
  }

  function addButtonToCard(card) {
    if (card.dataset.copyTagsBtnAdded) return;
    card.dataset.copyTagsBtnAdded = '1';
    card.style.position = card.style.position || 'relative';

    const btnHTML = `<button type="button" class="gm-copy-tags-btn"
        style="position: absolute; bottom: 6px; right: 6px; z-index: 100; padding: 4px 8px; font-size: 12px; background: #17181A; color: #fff; border: none; border-radius: 6px; cursor: pointer; box-shadow: 0 2px 6px rgba(0,0,0,0.2);">
        📋
    </button>`;
    card.insertAdjacentHTML('beforeend', btnHTML);

    const btn = card.querySelector('.gm-copy-tags-btn');
    if (!btn) return;
    if (btn.dataset.listenerAdded) return;
    btn.dataset.listenerAdded = '1';

    btn.addEventListener('click', async (e) => {
      e.stopPropagation();
      e.preventDefault();
      btn.disabled = true;
      const bv = extractBv(card);
      if (!bv) {
        showTempText(btn, '未找到BV');
        btn.disabled = false;
        return;
      }
      const tags = await fetchTags(bv);
      if (tags) {
        const ok = await copyToClipboard(tags);
        showTempText(btn, ok ? '已复制' : '复制失败');
      } else {
        showTempText(btn, '无标签');
      }
      btn.disabled = false;
    });
  }

  function scanAndInject() {
    const cards = document.querySelectorAll(SELECTOR);
    cards.forEach(addButtonToCard);
  }

  scanAndInject();

  const mo = new MutationObserver((mutations) => {
    for (const m of mutations) {
      if (m.addedNodes && m.addedNodes.length) {
        scanAndInject();
        break;
      }
    }
  });
  mo.observe(document.body, { childList: true, subtree: true });

})();

发布留言

登录以发布留言。