🏠 返回首頁 

Sina Weibo Hot Search List - Keyword Blocking (Enhanced Version)

Block the following tags in Weibo's hot search list: dramas, variety shows and other obvious purchase items, hot search ads, hot search keywords. You can customize tags and keywords, and support json import and export of tag and keyword lists.


Install this script?
// ==UserScript==
// @name         ##微博热搜榜-关键词屏蔽(增强版)
// @name:en      Sina Weibo Hot Search List - Keyword Blocking (Enhanced Version)
// @namespace    http://tampermonkey.net/
// @version      0.1.0
// @description  屏蔽微博热搜榜中标签为:剧集、综艺等明显买量条目、热搜广告、热搜关键词。可自定义标签及关键词,并支持json导入导出标签和关键词列表。
// @description:en  Block the following tags in Weibo's hot search list: dramas, variety shows and other obvious purchase items, hot search ads, hot search keywords. You can customize tags and keywords, and support json import and export of tag and keyword lists.
// @author       kawatabi
// @match        https://s.weibo.com/top/*
// @icon         https://www.sina.com.cn/favicon.ico
// @grant        none
// @license      GPL-3.0 License
// @require      https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/jquery/3.2.1/jquery.min.js
// ==/UserScript==
(function () {
'use strict';
let xAdListEl // 设置页面
let xAdCloseBtn  //设置页面关闭按钮
let xAdTips //提示标签
let keywordsListMap //热搜关键词
let tagListMap //标签
let adWrapper = $(".data ").find("tbody")
let adTd01Arr = adWrapper.find(".td-01") // 全部的标签 用于检索标签中为 • 的广告
let adTd02Tags = adWrapper.find(".td-02").find("span") // 关键词类型内数组
let adTd02Keyword = adWrapper.find(".td-02").find("a") // 关键词类型内数组
let adLens = adTd01Arr.length //热搜长度 如果大于50 则说明有上升的热搜
/** ==================== storageUtils ====================*/
/**
*  保存内容到 localStorage 中
* @param storageName 本地仓库名称
* @param storageVal 需要存储的值
* @returns {*} 成功返回存储名称 否则返回null
*/
let saveStorage = function (storageName, storageVal) {
if (storageName.trim() === "") {
throw new Error("saveStorage error:storageName does not empty")
}
try {
localStorage.setItem(storageName, JSON.stringify(storageVal))
return storageName
} catch (e) {
throw new Error("saveStorage error: save fail" + e)
}
}
/**
*  根据传入的 storageName 获取 localStorage 中的值
* @param storageName 名称
* @returns {any} 经过转换 的值
*/
let getStorage = function (storageName) {
if (storageName.trim() === "") {
throw new Error("getStorage error:storageName does not empty")
}
try {
return JSON.parse(localStorage.getItem(storageName));
} catch (e) {
throw new Error("getStorage error:get fail" + e)
}
}
//屏蔽的热搜列表
let blockList = []
init()
function init() {
addElementToBody()
addHeadLink()
initModalBox()
handleMenuBtnClick()
handleCloseBtnClick()
initData()
renderDelKeywordsList()
renderDelTagList()
disableAdItem()
disableTags()
disableKeyword()
resetIndex()
handleAddTagBtnClick()
handleAddKeywordBtnClick()
handleExportBtnClick()
handleImportBtnClick()
renderBlockListToBody()
}
/**
* 渲染频闭列表到页面中
*/
function renderBlockListToBody() {
let blockListEl = $(".x-ad-block-list-wrap")
blockListEl.siblings("span").text("屏蔽列表(只会显示本次被屏蔽的热搜)共 " + blockList.length + " 条")
let str = ""
$.each(blockList, function (i, item) {
str += `<div class="u-item"><a href="${item.el.get(0)}" target="_blank" title="点击前往热搜:${item.el.text()}">${i + 1},  屏蔽类型:${item.type},屏蔽内容:${item.el.text()}  </a></div>`
})
blockListEl.html(str)
}
/**
* 初始化时候读取本地过滤列表
*/
function initData() {
keywordsListMap = getStorage("keywordsListMap") || ["##少年团", "肖战", "王一博"]
tagListMap = getStorage("tagListMap") || ["剧集", "综艺", "电影", "盛典", "音乐", "演出"]
saveStorage("keywordsListMap", keywordsListMap)
saveStorage("tagListMap", tagListMap)
}
/**
* 添加标签按钮被点击
*/
function handleAddTagBtnClick() {
$(".x-btn-add-tag").on("click", function () {
let tag = $(this).siblings(".x-add-ipt-tag").val()
if (tag.trim() != "") {
tagListMap.push(tag)
xAdTips.text("添加成功")
saveStorage("tagListMap", tagListMap)
setTimeout(function () {
xAdTips.text("")
}, 3000)
} else {
xAdTips.text("输入标签名称后在添加")
}
})
}
/**
* 添加关键词按钮被点击
*/
function handleAddKeywordBtnClick() {
$(".x-btn-add-keyword").on("click", function () {
let keywords = $(this).siblings(".x-add-ipt-keyword").val()
if (keywords.trim() != "") {
keywordsListMap.push(keywords)
saveStorage("keywordsListMap", keywordsListMap)
xAdTips.text("添加成功")
setTimeout(function () {
xAdTips.text("")
}, 3000)
} else {
xAdTips.text("输入关键词后在添加")
}
})
}
/**
* 处理导出按钮点击事件
*/
function handleExportBtnClick() {
$(".x-btn-export").on("click", function () {
const data = {
tagListMap: tagListMap,
keywordsListMap: keywordsListMap
};
const dataStr = "data:text/json;charset=utf-8," + encodeURIComponent(JSON.stringify(data));
const downloadAnchorNode = document.createElement('a');
downloadAnchorNode.setAttribute("href", dataStr);
downloadAnchorNode.setAttribute("download", "weibo_filter_data.json");
document.body.appendChild(downloadAnchorNode);
downloadAnchorNode.click();
downloadAnchorNode.remove();
});
}
/**
* 处理导入按钮点击事件
*/
function handleImportBtnClick() {
$(".x-btn-import").on("click", function () {
const input = document.createElement('input');
input.type = 'file';
input.accept = 'application/json';
input.onchange = function (event) {
const file = event.target.files[0];
const reader = new FileReader();
reader.onload = function (e) {
const r###lt = JSON.parse(e.target.r###lt);
if (r###lt.tagListMap && r###lt.keywordsListMap) {
tagListMap = r###lt.tagListMap;
keywordsListMap = r###lt.keywordsListMap;
saveStorage("tagListMap", tagListMap);
saveStorage("keywordsListMap", keywordsListMap);
renderDelTagList();
renderDelKeywordsList();
alert("导入成功");
} else {
alert("文件格式不正确");
}
};
reader.readAsText(file);
};
input.click();
});
}
/**
* 重新为热搜编号
*/
function resetIndex() {
//如果总长度大于50 则说明有上升的热搜
if (adLens > 50) {
let resetEl = adWrapper.find(".td-01") //重新获取最新的子元素
let continueFirstFlag = false
if (resetEl.find(".icon-top").length > 0) {
continueFirstFlag = true
}
for (let i = 0; i < resetEl.length; i++) {
if (continueFirstFlag) {
continueFirstFlag = !continueFirstFlag
continue
}
$(resetEl[i]).text(i)
}
}
}
/**
* 隐藏包含 disableStartName 集合中关键字的热搜
*/
function disableKeyword() {
$.each(keywordsListMap, function (nameIndex, keyword) {
$.each(adTd02Keyword, function (i, adKeyword) {
if ($(adKeyword).text().indexOf(keyword) !== -1) {
$(adKeyword).parents("tr").remove()
blockList.push({
el: $(adKeyword).parents("tr").children(".td-02").children("a"),
type: `关键词(${keyword})`
})
}
})
})
}
/**
* 隐藏tag为 tagListMap 定义的内容的热搜
*/
function disableTags() {
$.each(tagListMap, function (i, tagItem) {
$.each(adTd02Tags, function (i, adTagItem) {
if ($(adTagItem).text().indexOf(tagItem) !== -1) {
$(adTagItem).parents("tr").remove()
blockList.push({
el: $(adTagItem).parents("tr").children(".td-02").children("a"),
type: `标签(${tagItem})`
})
}
})
})
}
/**
* 隐藏广告
*/
function disableAdItem() {
$.each(adTd01Arr, function (i, item) {
if ($(item).text() === "•") {
$(item).parents("tr").remove()
}
})
}
/**
* 渲染删除关键词列表 并且将删除后的数组保存到本地
*/
function renderDelKeywordsList() {
let delKeywordsListEl = $(".del-keywords-list")
let delKeywordsStr = ""
$.each(keywordsListMap, function (i, item) {
delKeywordsStr +=
'<div class="u-item"><span class="x-ad-txt">' + item + '</span><span class="x-delete-btn"  title="删除关键词  ' + item + '">删除</span></div>'
})
delKeywordsListEl.html(delKeywordsStr)
delKeywordsListEl.on("click", ".x-delete-btn", function () {
let index = $(this).parents(".u-item").index()
$(this).parents(".u-item").remove()
keywordsListMap.splice(index, 1)
saveStorage("keywordsListMap", keywordsListMap)
})
}
/**
* 渲染删除tag列表 并且将删除后的数组保存到本地
*/
function renderDelTagList() {
let delTagListEl = $(".del-tag-list")
let delTagStr = ""
$.each(tagListMap, function (i, item) {
delTagStr +=
'<div class="u-item"><span class="x-ad-txt">' + item + '</span><span class="x-delete-btn" title="删除标签 ' + item + '">删除</span></div>'
})
delTagListEl.html(delTagStr)
delTagListEl.on("click", ".x-delete-btn", function () {
let index = $(this).parents(".u-item").index()
$(this).parents(".u-item").remove()
tagListMap.splice(index, 1)
saveStorage("tagListMap", tagListMap)
})
}
/**
* 拖动模态框
*/
function initModalBox() {
//拖动功能
let modalBox = document.querySelector(".x-ad-btn-setting");
modalBox.addEventListener("mousedown", function (e) {  //鼠标按下的时候,得到鼠标在盒子里面的坐标
let x = e.pageX - modalBox.offsetLeft;
let y = e.pageY - modalBox.offsetTop;
document.addEventListener("mousemove", move);  //鼠标移动的时候,得到模态框的坐标
function move(e) {
modalBox.style.left = e.pageX - x + "px";
modalBox.style.top = e.pageY - y + "px";
}
document.addEventListener("mouseup", function () {  //鼠标弹起的时候,解除鼠标移动事件
document.removeEventListener("mousemove", move);
})
})
$(modalBox).on("click", function () {
xAdListEl.fadeToggle()
})
}
/**
* 添加自定义内容标签到页面中
*/
function addElementToBody() {
let settingsEl = '<div class="x-ad-btn-setting" title="热搜关键词设置,按住鼠标左键可拖动">热</div>'
let xAdEl = `
<div class="x-ad-list" style="display: none">
<div class="x-ad-header">
<div class="x-ad-title">热搜关键词设置(刷新页面生效)</div>
<div class="x-ad-tips"></div>
<div class="x-ad-close-btn" title="关闭设置界面">X</div>
</div>
<div class="x-ad-wrapper">
<div class="a-ad-menu-list">
<div class="a-ad-menu-list-item x-active-menu">添加过滤信息</div>
<div class="a-ad-menu-list-item">删除过滤信息</div>
<div class="a-ad-menu-list-item">导入/导出</div>
<div class="a-ad-menu-list-item">屏蔽列表</div>
</div>
<div class="x-ad-container">
<!--添加新过滤内容-->
<div class="x-ad-add-wrap">
<div class="x-add-tags">
<span class="add-tips">添加新标签</span>
<p class="x-add-item">
<input type="text" class="x-add-ipt x-add-ipt-tag" placeholder="请输入需要过滤的标签名称">
<button class="x-btn x-btn-add-tag">添加</button>
</p>
</div>
<div class="x-add-keywords">
<span class="add-tips">添加新关键词</span>
<p class="x-add-item">
<input type="text" class="x-add-ipt x-add-ipt-keyword" placeholder="请输入需要过滤的关键词">
<button class="x-btn x-btn-add-keyword">添加</button>
</p>
</div>
</div>
<!--删除已添加的项目-->
<div class="x-ad-del-wrap">
<div class="x-del-tags">
<span>全部标签列表(新增加的要刷新后才显示)</span>
<div class="u-list del-tag-list"></div>
</div>
<div class="x-del-keyword">
<span>全部关键词列表(新增加的要刷新后才显示)</span>
<div class="u-list del-keywords-list"></div>
</div>
</div>
<!-- 导入导出 -->
<div class="x-ad-import-export-wrap" style="display:none;">
<button class="x-btn x-btn-export">导出</button>
<button class="x-btn x-btn-import">导入</button>
</div>
<div class="x-ad-block-list">
<span>屏蔽列表(只会显示本次被屏蔽的热搜)</span>
<div class=" u-list x-ad-block-list-wrap">
</div>
</div>
</div>
</div>
</div>`
$("body").append(settingsEl)
$("body").append(xAdEl)
xAdListEl = $(".x-ad-list")
xAdCloseBtn = $(".x-ad-close-btn")
xAdTips = $(".x-ad-tips")
}
/**
* 关闭按钮被点击
*/
function handleCloseBtnClick() {
xAdCloseBtn.on("click", function () {
xAdListEl.fadeToggle()
})
}
/**
* 添加菜单栏点击切换事件
*/
function handleMenuBtnClick() {
$(".a-ad-menu-list-item").on("click", function () {
$(this).addClass("x-active-menu").siblings().removeClass("x-active-menu")
let index = $(this).index()
$(this).parents(".a-ad-menu-list").siblings(".x-ad-container").children().eq(index).show().siblings().hide()
})
}
/**
*添加head中的style标签
*/
function addHeadLink() {
let head = document.querySelector("head");
let styleEl = addElStyle();
head.appendChild(styleEl);
}
/**
*
* 添加css样式方法,脚本的所有css 都将在这里定义
* @returns style 标签
*/
function addElStyle() {
let style = document.createElement("style");
style.type = "text/css";
style.innerHTML = `
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.x-ad-btn-setting {
display: flex;
justify-content: center;
align-items: center;
position: fixed;
left: 0;
top: 50%;
transform: translate(0%, -50%);
border-radius: 5px;
width: 40px;
height: 40px;
text-align: center;
font-size: 16px;
background-color: #4FC3F7;
cursor: pointer;
user-select: none;
-moz-user-select: none;
-ms-user-select: none;
color: #fff;
}
/*设置列表*/
.x-ad-list {
display: flex;
flex-direction: column;
position: fixed;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
width: 500px;
height: 500px;
border-radius: 5px;
background-color: #fff;
box-shadow: 0 0 10px rgba(0, 0, 0, .3);
}
/*标题*/
.x-ad-header {
position: relative;
display: flex;
padding: 5px 10px;
font-size: 18px;
border-bottom: 1px solid rgba(0, 0, 0, .1);
}
/*标题文字*/
.x-ad-title {
font-size: 18px;
}
/*提示文字*/
.x-ad-tips, .x-ad-close-btn {
position: absolute;
right: 40px;
color: green;
font-size: 16px;
}
.x-ad-close-btn {
padding: 10px;
top: -5px;
right: 5px;
color: #333;
cursor: pointer;
transition: all .3s ease;
}
.x-ad-close-btn:hover {
transform: rotate(90deg);
}
/*主要设置部分*/
.x-ad-wrapper {
display: flex;
flex: 1;
background-color: #EEEEEE;
}
/*设置菜单 列表*/
.a-ad-menu-list {
display: flex;
text-align: center;
flex-direction: column;
width: 100px;
height: 100%;
cursor: pointer;
}
/*每一个菜单项*/
.a-ad-menu-list-item {
padding: 5px;
}
/*鼠标经过菜单显示的颜色*/
.a-ad-menu-list-item:hover {
background-color: #FAFAFA;
}
/*主要内容部分*/
.x-ad-container {
flex: 1;
background-color: #ffffff;
}
/*添加关键词*/
.x-ad-add-wrap, .x-ad-del-wrap,.x-ad-block-list {
padding: 10px;
}
.x-ad-del-wrap,.x-ad-block-list{
display:none;
}
/*每一个添加的行*/
.x-add-item {
margin: 16px 0;
display: flex;
/*justify-content: center;*/
align-items: center;
}
/*输入框*/
.x-add-ipt {
width: 250px;
outline: none;
height: 30px;
border-radius: 2px;
padding: 0 5px;
color: #333;
border: 1px solid #eee;
}
/*添加按钮*/
.x-btn {
width: 80px;
height: 30px;
border: none;
cursor: pointer;
}
/*活跃的菜单*/
.x-active-menu {
background-color: #fff;
}
/*列表盒子*/
.u-list {
margin: 5px 10px;
background-color: rgba(238, 238, 238, .4);
min-height: 186px;
max-height: 186px;
overflow-y: auto;
border-radius: 2px;
}
/*列表盒子中的每一个项*/
.u-item {
padding: 5px;
display: flex;
justify-content: space-between;
}
/*双数设置背景颜色*/
.u-item:nth-child(even) {
background-color: rgba(244, 255, 255, 0.5);
}
/*经过每一个项*/
.u-item:hover {
background-color: #FFB74D;
}
/*删除按钮*/
.x-delete-btn {
cursor: pointer;
user-select: none;
-ms-user-select: none;
}
/*鼠标经过删除按钮*/
.x-delete-btn:hover {
color: #ffffff;
}
/*删除关键词盒子*/
.x-del-keyword {
margin-top: 15px;
}
`;
return style;
}
})();